Editing Everything

Unreal Editor Vocabulary

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    I will start this tutorial by explaining a little of how the editor actually works. This editor is unlike many other editor that are around. It also differs from many 3D Programs that are available for purchase. You will find that most programs that are available will start the screen off with a huge "empty" area. Thus if you would want to build something, you will have to "add" to the world. What makes the Unreal Editor different is that the world that you start off with is actually a huge great SOLID block. It does not have any empty or blank space in it. Thus if you would like to create a room in the world, then you actually have to "subtract" it from the world. If this may seem a little "backwards" with the way that most editors work, then I agree with you, but at the same time, I do also think that this does make a lot of sense. In most of the other editors, you would have to create a solid "wall" to show the last part of a level (or world) before the editor would allow you to actually see it. Thus you would have to create a large number of addition brushes simply to have a finite size of the level. With the Epic Editor (for Unreal) you do not have to create a "final" barrier to your world, but simply each time you subtract a room (or space) from the editor, then it automatically adds to the area that you can travel in the game. Thus, it does make our lives somewhat easier, and also does make a smaller load on the processor of the PC playing it, as it does not have to count and use as many brushes, as if you would have extra brushes to mark the final point of a level. Ok, now that we know a little of how the editor works, let's get into some of the more technical words that you will probably hear mentioned a lot in my tutorials and other people when they talk about the editor. The amount of detail I will go into will vary on how important I think something is, and if it is really important that you know what each word means.

    • Brushes

      • Solid Brushes
        A solid brush is a brush that has been placed into the level, and the builder brush that created it was solid at the time. When you select the properties of a brush (from a primitive) you will be able to select one of two options. You can choose SOLID which means that the brush you create is a 3D shape that has got no "insides" to it. It is a basic shape that has got an outline, but no "inside" to it. If you add a brush like this, you will add in a new section to the world, and there will be no way to get into it.

      • Hollow Brushes
        A hollow brush is a brush that when created, actually is an outline, and has got "another smaller shape" inside it. Thus when you add (or subtract) it into the level, you will have a shape that appears hollow on the inside. This gets hard to explain here. Let me use an example here. If you create a cube that is hollow, you will actually have a brush that is more like a cardboard box, rather then a child's playing cube, that is entirely solid in the middle.

        • Builder Brush
          The builder brush is actually the RED BRUSH that you first see as a red cube when you open the editor. This will be your most important tool when you are creating and editing levels. While it might seem a little "primitive" at first, you should find that with a few of the things that you can do with it, you will be making it into whatever you like in no time al all. If you choose to click on any of the primitives (The shapes on the toolbar to the left of the screen) then your builder brush will change to that shape, and you can then add and subtract with that brush.
          This Tool, is only a temporary brush, and does not actually make any difference in the level itself. When you are "rebuilding" your level, you will find that it does not affect anything at all, as it is really only "a fake" until you use one of the other tools to make it permanent.

        • Subtracted Brush
          A brush that has been subtracted will show on the editor 2D views as an orangy brown color. This has been made from the builder brush at one time, and then the subtract tool has been used, to permanently place it in the level. If this brush has been placed in an area that was solid before, then you will be able to travel into that section of the game. If you subtract a hollow brush into the game, then you will be able walk inside the brush.

        • Added Brush
          When you "add" a brush into the world, you are actually creating another solid. Thus, you can only "add" a brush into the world where there is a hollow area, otherwise you will be adding something to a place where something already exists (This should mean completely useless) When you add a brush to the level, you will see it appear as a Bark Blue shape in the 2D views.

        • Special Brush
          A special brush can be added to just about anywhere in the world. You will see them as Green colored shapes in the 2D views. Special Brushes can be used to add water, a transparent "barrier" and many other useful things, although you will most likely find these out either for yourself, or as you start reading some more of the tutorials.

        • Mover Brushes
          A mover brush is a brush in the world that will actually move. This can be created by either joining a "trigger" to the mover, or by touching the mover, but that is all explained in the related tutorials. You wil not see the textures on a mover in the 3D view, but only see the purple outline and there will be no way to change the texture alignment or anything like that, so you have to be sure that everything is perfect before you create it.

      • Movers
        Movers are brushes that can be set to move in the level, and are explained in the Brushes section.

    • Triggers
      A trigger can be used for a lot of things. The most common use it to activate a mover with a trigger. A trigger will appear in the editor as a little question mark next to a cube. To set a trigger to activate a mover, simply change the "tag" of both trigger and mover to be the same. Triggers are explained once again, in tutorials, so I will not go into to much detail here, although they can be used for just about anything in your level (world).

    • Intersecting/Disinteresting
      You can create many things with the primitives that are supplied in the editor, although a lot of the time you find that your geometry will overlap. If you have things that overlap, you can find that your level may not rebuild properly. You can find that things will appear to have large "black" area that do not work properly. You can however use the two tools (intersect/disinterest) to make the builder brush either cut everything OUTSIDE the solid, or to make the builder brush appear only within the brush (s). This can be rather tricky to explain here in text without being able to show a quick animation, but what it means is that means is that your red builder brush will be "cut" to only what is either inside or outside the bushes that are in your level already.,/li>

    • Rebuilding
      When you have created a brush (or more hopefully ;) then you will have to compile it into an actual level. When you press the rebuild function (Either press F8, or choose rebuild from the options menu) setting it to "rebuild" will take a few seconds to quite a few minutes (depending on the complexity of the level) and it will be all ready to play. There are a few settings within the window that you can choose to either turn on or off but they are explained under their own heading, although there is a list of them here. BSP, LIGHTING, GEOMETRY, OPTIMIZATION. When you rebuild make sure that you do save the level, as you will sometimes find that there may be errors and some of the can actually crash your system. Actually it is a good idea to get into the habit of saving the level quite often and having a few little "backup" files that are kept there just in case...

    • BSP
      This is what will decide where the player will be able to go, and where they will not be able to go. Any SOLID brushes will affect the BSP of the level. If you have got an area that has got a large amount of adding and subtracting in the same place, then you may experience something that is called BSP holes, which appear as large black holes in your level, and most often also result in the player not being able to move through the area properly. If this is near the end of the level, or near an area that "ends" with a solid area, then you may also experience the dreaded HOM. (This is explained below).

    • HOM - Hall of Mirrors
      This is the bane of all editors. You will have most likely seen eh HOM before, but simply put it down to bad level editing. It is - kinda. You will most often see the HOM where you have got an area or even maybe a transparent texture that is in the last place in a level. Ok, this is hard to explain, but for example, if you have got a room in the level, and there is nothing beyond the room. You would normally place a texture on the walls that is not see through right? If you placed a texture that has got invisible areas, when you try to play the level, the game engine will try to "cover" the holes there, and it does it by "mirroring" the last thing shown there. If you ever find a shimmering area where things have stopped moving and it looks bad, then most likely this is what has occurred. There is no "one way fix" to get rid of the HOM, but please check your textures to make sure that they do not contain any areas of transparency, and that in the 2D views bits of your map are not disappearing.

    • Lighting
      Lighting in the level is pretty basic. It simply means that you will have some sort of illumination that is in your world so that the players will be able to see where they are and what they are doing. Lighting may however take the form of many different things. The easiest way to make a light is to right click in the level on a texture (in the 3D view) and choose "add light" from the drop menu. See also Dynamic lighting.

    • Dynamic Lighting
      Dynamic lighting will greatly enhance the look of your level, although it may actually slow down the level, and cause some less powerful machines to drop frames. Dynamic lighting simply refers to lights that do things. You can create lights that shimmer, or lights that are spot lights and rotate, lights that pulsate, or lights that simply "strobe". There are a LOT of things that you can use, but as mentioned earlier here, they will use a large amount of resources (compared to a normal light that is) to use, and some lower end machines may suffer a large drop of frame rate.

    • Geometry
      Geometry refers to the actual brushes that are in your level. These are the things that your players will walk over, and also where they will be able to see. To learn how to create brushes and geometry, refer to the Brushes section of this document.

    • Optimization
      There are a lot of questions asked about the "Optimization" settings that can be changed within the rebuilder, although you should not actually change any of them in the BETA Editor that has been released by Epic with Unreal. I have played with the optimisation settings before, and the only good that it did, was to kill my level. Trust me on this one, until there is a fix for the settings - Do NOT change them.

    • Zones
      Zones can be created in the editor. Zones will be able to hold specific areas in the map. A zone is really kinda like a level in itself. For example, if you have an area with water in it, it is actually a "water zone" or you can create an area with fog in it, and to make the level play faster, you cn restrict the area that the fog is visible from, then create a Zone around it. This will then allow the CPU resources to be used for other things in the game (like frame rate).

    • Portals
      Portals can be created in the level, to allow players to simply "walk" (or fall, or fly or whatever) from one place in the level, to another place. These have a nice tutorial written on them, so I will not go into too much detail here.

    • Textures
      Textures are simply images that are used to "paint" the brushes in your level with, so that people can actually see what is stopping them from going forward, or what is stopping them from falling through the ground.

    • Wave or .wav
      This is a format for storing sound. It is the basic format that most people use to import sounds into the game and then save them for use in the levels. Wave files can be explained much more thoroughly in the Booklet of your Sound-Card, so I will not explain them here in any more detail.

    • Texture Packages or .utx
      These are simply files that contain many images for use as textures in the levels. There are tutorials on this site, that will explain how to create texture packs and how to import files into the engine for use.

    • Scaling - Textures
      When you have a texture on the brush, you can actually change the size of the display. If you have an image that is too large, or small for the brush, you can actually change the scale in which it is displayed.

    • Scaling - Brushes
      Brushes just like Textures can be scaled to change the size of them, however, if you want to create a mover from anything, you CANNOT (and I can't stress that enough) used scales brushes during any part of the construction of the mover. If you do, everything will appear to be fine, until you actually try to use the mover or try to walk up to it. At this point, you will find that the brush that was scaled, will actually still be "unscaled" even though it may look like everything is fine.

    • Skybox
      The skybox is the part of the map that is displayed whenever there is a texture 9or face of brush) that has been set to "Fake Backdrop". This is most useful when you have to make a "sky" or a background that you want seen from any part of the map.

    • PlayerStart
      A Playerstart will be the place in your level that the player begins when you start the level. These can be placed just about anywhere you like, although it is a good idea to make sure that they are not in a place that the player can get hurt immediately.

    • PainZone
      A Painzone is an area of the map that is zones all around, and when the player walks into it, they will start losing health points. This loss of health will continue until the player either leaves the pain zone, or dies. Water is actually a painzone, although there is a delay in it. The delay is there to allow the player to use the air in his/her lungs (i.e. hold their breath) and when they start running out, they will start to lose health.

    • KillZone
      A Killzone is quite similar to the above zone, although rather then just making the player lose health slowly, they are actually killed in the spot. It does not make a difference if the player is in GOD mode or not. They will die as soon as they step into a Killzone.

    • Frame Rate
      Frame rate is really simple. It refers to the number of frames that the computer can show in a second. The higher the number, the smoother the display will be. To try to improve your frame rate on a level, make sure that there are as few a number of brushes and as few a number of Dynamic lighting as possible. There are a large number of influences that will determine the frame rate, but generally speaking, try to use as little "goodies" as you can, and the level will play better.


Editor Tool Buttons

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    Basic Building Brushes:

    Add brush to world. This button is used to "add" a brush to the world. Any brush can be added to the world, but make sure that you don't try to add something to a piece of the world that is already solid, as this can turn out quite nasty when playing the game or rebuilding...

    Subtract brush from world. This button will "carve" out the brush from your level. Do not try to subtract a brush from an area that has already been subtracted - as this won't work and can have adverse (bad) effects on your level.

    Brush intersection. This is the "intersect" button. It is used to change your brush. Say you have a "cube" brush, but only want to cut out half a cube from a solid wall. You could go through the cube properties and change the shape of your brush, or you could simply move the cube to where you want it to go and then press this button. This will make a new brush for you - but it will only be where the solid wall was before. It is also good for making complex objects into a single brush. Say you want to make a fireplace, and you want to use it in a few places - create it (bit by bit) and then place a cube brush over the top (so the cube {or whatever} encompasses the fireplace totally) and when you press this button, your new brush will be EXACTLY the same as what you created using many little bits.

    Brush disintersection. This does the opposite of what the intersect button does. It will select the parts of the brush that are in an area that is not solid - and create them into a new brush for you.

    Add Special Brush. This allows you to create "special" brushes to your map. These can be a wide range of things, such as windows, water levels, portals and the like. It is normally used in combination with the "sheet" brush.

    Add movable brush. This button will create a mover for you. It will use whatever brush you have currently selected. When using this brush however, make sure that the brush you have selected has NOT been stretched in any way, as it won't work properly...

    Build a cube. This will create a cube brush for you. If you right click on it, it will give you an option to go to cube properties. This will allow you to change the height, depth etc of the cube brush you will create.

    Build a Sphere. This is the same as the cube, but it will create a round ball shaped (well a sphere really) brush. Once again right click on it to alter the properties of the brush.

    Build a cylinder. This will create a cylinder for you, that you can use like any other brush.

    Build a cone. This will create a cone (rounded pyramid) that you can use like any other brush.

    Build a stair. This will create a straight flight of stairs. These stairs will not turn or curve as they go up.

    Build a spiral stair. This will create a rounded set of stairs that can be set to form a very tight spiral staircase.

    Build a curved stair. This will simply create a rounded set of stairs that are similar to the first set, but they curve around to a side when they have been built.

    Build a sheet. This creates a 2 dimensional sheet. It can be used for a VERY LARGE number of applications. One of the most common is to create a water plane. This tool does however require more practice then the other brushes, as it is not a 3D brush and can easily "wreck" a level. It should NOT (I can't stress this enough) be used to create walls and other solid shapes. (Well at least until you are quite familiar with the editor).

    Advanced Building Brushes:

    Move Camera. This is the normal view button. It is normally toggled to "on". It lets you move in the views. My advise is to leave it set to what it is...

    Zoom camera. I can honestly say I have no idea what this button is supposed to do. I have tried it a few times, but normally end up miles away from where I am building, so I always leave it set to the button described above.

    Rotate brush. This button is used to rotate the brush that you have currently got selected. It is used by holding CTRL and with a combination of mouse buttons (Left rotates X axis, right rotates Y axis and both rotate Z axis) allows the brush to be rotated to any angle.

    Sheer brush. This brush allows you to "skew" the brush. That is, it allows you to 'lean' the brush to a side.

    Scale brush. This button will allow you to change the size of your brush. That's right, once again CTRL and the mouse will activate it when it's selected.

    Stretch brush. This will alter the size of your brush, but it will do it one axis at a time. Which basically means it's great for adjusting something that is almost perfect.

    Snap Scale Brush. This button will allow you to stretch a brush along all three axis' , but at the same time it will "snap" to the grid. This is VERY handy to enlarge or shrink brushes, as they are easy to match up later.

    Select all polys. This brush will select ALL the things in your map. I don't know what the point is, but the option is there...

    Select all actors. Once again, I am not sure. But look on the bright side, I haven't used it - and still made great maps, so it probably (feel free to prove me wrong) isn't all that integral to the editor.

    Select actors inside brush. This is another of the buttons I haven't used very much - or at all. I can't really tell you what it is used for...

    Select none. This will make sure that "none" of the brushes or textures are selected. In a way, it 'unselects' everything...

    Invert actor selection state. This button will replace the selection that you currently have. Sorry I can't say more, but yet again, it's a brush that I have little use for.

    Replace selected brushes. This button will replace the brush with what you currently have selected.

    Replace selected non-brush actors. This button will replace the actors selected with what you currently have selected.

    Undo last operation. I don't think that anyone there needs a detailed explanation of what an "undo" button does, But on that note - just remember that you can't undo past a rebuild. I mean that if you rebuild your level and don't make any changes - then you won't be able to undo something that was changed before you last rebuilt.

    Redo operation. If you accidentally pressed "undo" once too many, then this button will redo the last action that you undid.

    Pan textures. This will move the texture that is selected. It is used mainly for aligning the texture to match up with other textures. If you have more then one brush with a texture, and you want them to line up - then this is the tool for you.

    Rotate textures. This button will allow you to rotate a texture so that it matches the direction of other textures - or simply faces the direction that you want it to face.

    Drawing Region: Selected Actors. This button will "hide" all the brushes that are in your level. It's great for adding in detail and things like that when you don't want to see all the other brushes.

    Hide Selected Actors. This button is similar to the one above, but it will only hide the brushes that are selected. You can select more then one brush at a time to hide by pressing CTRL and select as many as you like.

    Drawing Regions: Off. This will "bring back" any brushes that were hidden using the buttons above.

    Drawing Regions: Brush Z (Depth). This will hide the Z axis apparently. I can put this into the pile of buttons that I never use.

    Toggle vertex snap. This will toggle the grid snap function of placing brushes. It is generally used for adding the details when the grid is in the way...

    Get Help. Well, now here is a useless button - as you are probably using the BETA UnrealED, this button has absolutely NO function whatsoever, so don't bother trying to find the help file...

    Camera speed. This will change the speed with which your moves moves brushes and other objects in the views.

    Toggle grid mode. This button will snap objects to the grid when they are moved around in the editor.

    Toggle rotation grid. This will toggle whether you want rotational grid snapping. This button makes it rather difficult to rotate a brush when it is large and also makes it difficult to align things to angles made by sides of cylinders for example, but makes it a LOT easier to align general angles in the editor.


Introduction to Brushes

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

A Brush is really a 3D shape that is used to create the environment that the player will be able to travel in. A brush can take many properties, which are described in the brushes reference section of this file, but put simply a brush is a 3D shape that is used (most commonly) with other brushes to create the level.

If you are coming to the Unreal Editor from another 3D application, you may know the term Mesh, which would be a close relative of the brush. In the Unreal Engine, a mesh is slightly different, but the main concept is the same.

A Brush may technically be any 3D shape (from the primitive shapes such as Cube, Cone, Sheet etc through to complex shapes such as stairs, mountains, anything imaginable) inside the editor.

Brushes are used in conjunction with CSG Operations, which will turn the information that the brush holds (about size, position, shape etc) into something that is visible (or invisible for that matter) and interacts with the player in some way, like blocking them, showing a texture, creating a Zone Portal or providing a set of stairs to reach the platform above them.

There are many different types of brushes, but they are all related in their native information about the 3D world that they are used to create. The only exception is the Active Brush, which is used to create the other brushes with and does not actually influence the level in any way.

This shows the types of brushes available in their default colors. The numbers correspond to more information on each type in the list below. There are two images of each brush type, the top image shows the brush as unselected, and the lower image shows the selected brush. For more information regarding brush types, read the brush reference section in this file.

  1. Active Brush This is the brush used to create all the other brushes in the Unreal Editor.

  2. Subtracted Brush This is a solid brush that has been subtracted.

  3. Added Brush This is a solid brush that has been added.

  4. Non Solid Brush This brush has been added as a Non Solid.

  5. Semi Solid Brush This is a semi Solid Brush.

  6. Mover Brush This is a brush that can move inside the environment.


Constructive Solid Geometry

Constructive Solid Geometry (CSG)

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The Unreal Editor uses Constructive Solid Geometry (CSG), which is a concept (or design plan) for building a three dimensional world. This concept uses brushes, which are like building blocks for the final three-dimensional environment (or level depending on choice of terminology).

A Brush is the name given to a 3D shape, which is used to define what a player can see, where they can walk, and how the world is presented to them. These brushes are often small parts of the entire environment, and are used most commonly as individual segments of the entire environment.

In the Unreal Editor a "blank" or empty environment is actually a totally solid cube. This means that the first brushes that are used are subtractive brushes. This means that they subtract the solid space within the environment, leaving a void that players can move within.

Constructing a room that a player can walk within is very simple with CSG. Remembering that the world starts as a huge solid (filled) shape, it is a simple matter of creating a cube (or any other 3D shape) and subtracting it. This will leave a void in the shape of the brush that was used, and the player will be able to move within that area.

This method of construction also means that to create a simple room, it only takes a single subtracted brush, rather than creating a floor, 4 walls and a ceiling (assuming that a cube is made). The brush then has 6 surfaces (faces) that can be individually textured to suit the environment.


Brush Order Defined

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The Brush Order is very important. Because brushes in the Unreal Engine are ordered, the BSP cuts are made following the brush order. Most commonly, there are two brushes that combine to create a final shape. Firstly the subtractive brush, then the additive brush. This seems simple, as the order is as follows:

    The Subtractive Bush is first, creating the basic shape of the room to be created, then the Additive brush follows, creating the additional features for the room.

However, there is often the need for more than two brushes to make up a particular shape. Another example would be the following:

    We want a simple room, with a pillar in the middle of it, with a hole in the pillar that a player can see through.

While the order of brushes is not often an issue, complex maps and possible display problems can sometimes warrant the need to change the order of brushes. The Unreal Editor will automatically set the order of brushes based on the order that they are created in making editing much easier, but the concept of brush order is an important one, so lets explain it in more detail.

Click here for a detailed explanation of a simple room

    This example shows the room described above, and shows the potential pitfalls if the order of the brushes is not correct. Reading through this example will explain just how the brush order will affect the environment and what is created.


Brush Order Example

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The following image sets out the environment that we wish to create.

This image shows us the room that we want to have.

This image shows the exact same room in the overhead 2D view.

As you can see, it requires three brushes to create this environment. The proper order is as follows:

  1. The first brush created is the room itself, giving the player room to walk around in.

  2. The second brush is the pillar itself, because it must be added to the space that the first subtractive brush creates.

  3. Finally, the hole in the pillar must be subtracted after the pillar has been put into place.

Sounds simple enough, but lets see what happens if the order was wrong. Changing the order of the hole in the pillar to the first CSG Operation will result in the following (Following the way that the Unreal Editor creates the environment, it would do the following based on the order of brushes.):

  1. Finding the first brush (this time, it is the hole inside the pillar) it subtracts the space from the solid space. This leaves us with a tiny room.

  2. The next brush is now the original room. Because the room is also a subtractive brush, the full sized room is now subtracted. This leaves us with a larger room, with a smaller room inside it. At this point however, the smaller room is not visible, nor does it have a purpose. An area cannot be subtracted twice, hence only the larger brush has any consequence as it is second in the order.

  3. Finally the editor comes to the third brush. This is the pillar, which is then added to the larger room. Even though the hole in the pillar has been subtracted, the pillar is added after the hole has been subtracted, hence it overrides the hole. We are left with a room and a solid pillar in the middle of it.

This image shows the same room with the order changed as described above.

This image shows the same room, after the order of the brushes has been changed. It is noteworthy to see that the brush that makes the hole in the middle of the pillar can now only be seen where the pillar does not cover it, unlike the 2D image above, where the sides are seen over the top of the pillar brush.

For more information regarding changing the order of brushes in the Unreal Editor, refer to the Brushes entry in the Unreal Editor Reference under Changing Brush Order.


Basic CSG Operations

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

Constructive Solid Geometry Operations are used in conjunction with Brushes to construct the environment.

The most commonly performed CSG Operations are Addition and Subtraction. Both place a new brush into the environment. When this new brush is placed into the environment, it uses the current shape, position and rotation (and all the other properties) of the Active Brush (see the entry for the Active Brush in the Important Concepts section of this file for further information on the Active Brush). Once the CSG Operation has been performed (e.g. Additive, Subtractive etc) the Active Brush is recreated, allowing for the next operation. After an operation has been performed, changing the Active Brush will not affect it in any way. Only through changing the brush that was placed in the operation can the area be changed.

An Additional Operation converts the Active Brush into a new Added Brush, filling the area enclosed within the bounds of the brush with solid (impassable) area. In a solid space, this has no real effect, however in an empty space, this creates an impassable area in the shape of the brush.

    A simple example of an Additive operation would be a pillar standing within a large open area. The large open area is "subtracted", leaving space for the player, then the pillar is "added" creating an impassable area that blocks the player in any situation.

A Subtractive Operation creates the opposite effect. It converts the Active Brush into a Subtracted Brush, leaving the area inside it empty (thus allowing a player to be inside that area). Within a solid space, a subtractive operation creates a void that the player is able to pass through. Creating a Subtractive Operation within an area that is already solid is meaningless – empty space cannot be subtracted from to get any effect.

    A good example of a Subtractive Operation would be a cave. The area around it is completely solid and impassable, yet the area within the rock is subtracted, allowing passage.


The Active Brush

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The Active Brush is a special type of brush. It is the only brush actor in the Unreal Engine that does not actually influence the final environment in any way. It is a go-between tool used to create other brushes. The Active Brush is highlighted in red, and never actually has any solidity.

    It can be well described like a mould used to create a brick. The mould itself does not get used when building a wall, but rather is used to create the bricks that will finally be used to make the wall.

When a CSG Operation is performed, the Active Brush is used, and the properties that it has (size, location, rotation etc) are used to create a new brush in it"s place. The Active Brush can then be used to create the next brush through the next CSG Operation. However, not all properties can be set in the Active Brush. For example, the Active Brush does not contain information on the texture to be placed onto the brush surfaces (This is not entirely true, but for the time being, assume that it only contains information as to the physical shape, size and location of the brush).

Unlike other brushes in the Unreal Editor, the Active Brush can be changed on the fly, with new size settings, location information and as soon as a CSG Operation is performed, these settings are used to create the new brush. While the Active Brush does start as a cube, but can be any shape at all. It is not limited in any way. Through the use of the Brush Building Tools in the Unreal Editor, almost any shape can be made through the Active Brush.


The Additive Brush

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The Added Brush calls the Additive CSG Operation, filling an area previously taken out with the Subtractive CSG Operation (it fills back solid space to an area inside a subtracted brush). Placing an Added Brush into an area that is already solid is meaningless, as it will not double fill the area.

The Added Brush is a solid brush, and will create solid space where there is void, thus blocking the player from movement in the solid space.

The Added Brush will only change after a rebuild has occurred, as it relies on the CSG Operation to create the effect that it has, and CSG Operations only occur during the rebuild itself.

The Added Brush like all other brushes (except the Active Brush - which is a special editor brush) takes its form from the Active Brush when a CSG Operation is performed.

To place a Additive Brush into your level, shape the Active Brush and place it where you want the Additive Brush to be, then click the Add button. (shown below).

This will create the Additive Brush.


The Subtracted Brush

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

In the Unreal Engine, a Subtracted Brush creates an area of void, which the player is then able to move in. As any environment in the Unreal Engine starts off as solid space, at least one subtracted brush MUST be included in any level that is playable, as without it, there would be no physical space for the player in the environment.

This is a Solid Brush, and it makes BSP cuts to the level. A Subtracted Brush that is placed within a solid area will create a hollow area. However, if it is placed within another hollow area, it will not create a double subtracted area, but in fact has no further effect.

This brush type is used in conjunction with the Subtractive CSG Operation.

The Subtracted Brush will only change after a rebuild has occurred, as it relies on the CSG Operation to create the effect that it has, and CSG Operations only occur during the rebuild itself.

The Subtracted brush, like all other brushes (except the Active Brush - which is a special editor brush) takes its form from the Active Brush when a CSG Operation is performed.

To place a Subtracted Brush into your level, shape the Active Brush and place it where you want the Subtractive Brush to be, then click the Subtract button. (shown below).

This will create the Subtracted brush.


The Mover Brush

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

Mover Brushes are a special type of brush in the Unreal Engine. They are brushes that are actually able to move within the Engine during play. This makes them unique from the other brush types, which are static. Mover brushes do not create BSP cuts hence they do not complicate the BSP tree in a level (That is good for framerate!) They can however block a player (and do so be default) though they can be set to not block anything.

A Mover brush is made by creating the shape using normal Additive and Subtractive brushes, then Intersecting the Active Brush with the shape to form a single brush from the (often) complex shapes wanted for the mover brush. (Intersecting Brushes is explained thoroughly in the Unreal Editor Reference Section, within the Intersection/Deinterserction topic). Using this method is also the only way (though Epic is looking at this matter) to assign a texture to the mover itself. Once the brush itself is created, the Add Mover button (shown below) can be used to place the mover within the level.

Creating a mover is explained in much more detail in the movers section of the Unreal Editor Reference in this file.

To place a Mover Brush into your level, shape the Active Brush and place it where you want the Mover Brush to be, then click the Add Mover button. (shown below).

This will place the Mover within your level.


Brush Solidity

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

Brushes in a CSG environment can have a few settings for Solidity. The Solidity of a brush defines how it interacts with a player and what effects it has on the environment as the engine is rendering it, and the BSP (Binary Space Partition) as the level is played.

Many of the brushes that are used will be Solid. This means that they not only make BSP Cuts (This is explained in more detail in the article titles Introduction to BSP) but they either block the player (Additive CSG Operations) or allow the player passage (Subtractive CSG Operations). If you would like to know more about CSG Operations, read the articles on Constrictive Solid Geometry in the Introduction to Editing Section of this file.

A Solid Brush is the only type of brush that will create a BSP Cut, and allow the player to collide with the brush, meaning that any brush that is subtractive (creating a place for the player to walk) has to be Solid.

A Non Solid brush type can be added to the level, but it will not block the player in any way. A Non Solid brush will also not make any BSP cuts. This means a few things:

  • Firstly, it means that a non solid brush is will most often be used as a decoration of sorts. It can only be placed inside a Subtractive Solid Brush. Putting this type of brush anywhere else will have no effect. Why? Because the brush is Non Solid, it doesn"t make any BSP cuts, and without BSP cuts, it will not create an area for the player to move within.

  • Secondly it means that a Non Solid brush reduces the Node Count of the level because it does not make BSP cuts. This can be important in the final framerate of the level when it is played.

  • Lastly, it means that a Non Solid brush can be used as a Zone Portal very well. For more information regarding Zones and Zone Portals, refer to the Zones information within this file.

A Semi Solid brush is really a mixture of the Solid and Non Solid brush types. It takes properties of both. It can block a player or actor (e.g. a bullet) and it doesn"t make BSP cuts to the level (From information on Non Solid Brushes, you should see that because it doesn"t make BSP cuts to the level, it will reduce the Node Count in the level). However, because it doesn"t make BSP cuts to the level, you should also see that it can only be used as an Additive Brush. A Semi Solid brush however cannot be used to close off a Zone. It is also a Dark Horse as far as brushes are concerned, as it can cause problems with player collision at times. Semi Solid Brushes should be used with caution and intuition.


The Semi

The Semi-Solid Brush

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

Semi Solid Brushes are a special brush class, somewhere between Non Solid brushes, and Solid Brushes. It is a special class, because it takes attributes from both of those brush types. It will block a player, and it will block actors, but at the same time, it will not create BSP cuts, and it will not block a zone.

Semi Solid brushes do not create BSP cuts, nor do they call the CSG Additive Operation (meaning that the area within them is technically still void, though it blocks the player from entering it) which means that a Semi Solid brush can only be an additive brush. This brush cannot be used to create a new room within a solid space, it can only be used to create a blocking shape within an area that the player can already get to.

As a Semi Solid brush does not make any BSP cuts, it can well have a beneficial affect on framerate. Even though the engine will still have to display the brush, because it does not make BSP cuts, it often means that the brush itself is simpler for the engine to display, and that in turn means that the area around it can be simpler for the engine to render.

Semi Solid brushes are most commonly used as either decorations inside an area, or they are used to create parts of a level that do not require BSP cuts (for example, a pillar, or piping running along a wall). This is because of the lower BSP complexity that they confer upon the level due to lack of BSP cuts (This really is very important!).

To place a Semi Solid Brush into your level, shape the Active Brush and place it where you want the Semi Solid Brush to be, then click the Add Special button. (shown below).

This will open a dialogue window (shown below). Select Semi Solid from the Solidity options presented, and click OK. This will then create the Semi Solid Brush.


The Non

The Non-Solid Brush

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The Non Solid brush creates a shape that, while visible does not block a player or any other actors. A common example of a non solid brush is the surface of a pool of water. The surface is visible, there is a texture on it, but it does not block the player in any way. Non solid brushes can be any shape or size.

Non Solid brushes do not make any BSP cuts, and are therefore beneficial to framerate. Due to the fact that Non Solid brushes cannot block the player or any other actor, they are always used as Zone Portals, creating an invisible barrier between two zones, though not actually stopping the player in any way.

Changing a Non Solid brush will only be visible in the 3D view after a rebuild has occurred.

A Non Solid Brush, like all other brushes, (except the Active Brush - which is a special editor brush) takes its form from the Active Brush when it is created in the environment.

    It is important to note that any sheet brush that is created is always created as a Non Solid brush, even if it is placed into the level via pressing one of the other CSG Operators (like Add or Subtract). The sheet brush can actually even be displayed in a blue color (normally defining added brushes) or any other color, but is automatically treated as a Non Solid. This is especially important to remember when creating a shape that you want as a sheet (like a fence, or grilled floor) which in itself will not block the player, but the player should be blocked when trying to walk through. If this is the case, an Invisible Collision Hull can be used to give the impression that the sheet is in fact blocking the player. However, it is noteworthy to remember not to place the Invisible Collision Hull directly over the sheet, as this often causes BSP errors, resulting in display problems.

To place a Non Solid Brush into your level, shape the Active Brush and place it where you want the Non Solid Brush to be, then click the Add Special button. (shown below).

This will open a dialogue window (shown below). Select Non Solid from the Solidity options presented, and click OK. This will then create the Non Solid Brush.


Editor Tool Buttons

Editor 2.0 Toolbar Buttons

    By: Brad 'BadDog' Streng

    bstrange@hmcltd.net

    Description excerpts from:

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    unrealed.exe

    and 'astro'

    astro@planetunreal.com

    UED Resource Lab

    Functions / Modes:

    Move Camera. This is the normal view button. It is normally toggled to "on". It lets you move in the views. My advise is to leave it set to what it is...

    Vertex Editing. Vertex Editing is used to manipulate the points, or Vertices of a Brush. After selecting the Vertex Editing button, you will notice the pointer icon has changed. Click on the Brush you wish to work with. The vertices are now gray. Hold down Ctrl+Alt and drag a selection box around the points you wish to move. Once you have selected the points they will turn white. Hold down Ctrl then left click to move the points to a new position. If you are using the red builder brush, perform a Transform Permanently BEFORE you add or subtract the brush. If it is an existing brush, right click on it and perform a Transform Permanently then build. You can not edit a Brush that has been Transformed Permanently. If the Brush is going to be in an area where a player wont touch it you can make the Brush semisolid. This in some cases can cut down on BSP holes/cuts and speed up the game.

    Scale brush. All Brushes can be scaled. Scaling can increase or decrease the size of a Brush on the fly. One disadvantage of scaling is you do not have control over exact measurements. Click the Brush Scaling button and again the pointer icon will change. Left click a point on the desired Brush to activate that vertex. Ctrl + either right or left click will scale to Brush in a different direction. The active side that is being scaled depends on the vertex you choose to start with. When finished, perform a Transform Permanently.

    Rotate brush. This button is used to rotate the brush that you have currently got selected. It is used by holding CTRL and with a combination of mouse buttons (Left rotates X axis, right rotates Y axis and both rotate Z axis) allows the brush to be rotated to any angle.

    Pan textures. This will move the texture that is selected. It is used mainly for aligning the texture to match up with other textures. If you have more then one brush with a texture, and you want them to line up - then this is the tool for you. With this button activated, you can pan a texture using Ctrl + left click and Ctrl + right click.

    Rotate textures. This button will allow you to rotate a texture so that it matches the direction of other textures - or simply faces the direction that you want it to face. Highlight the texture in the 3D viewport you wish to rotate. Now you can left OR right click while holding down Ctrl and the texture will rotate.

    Brush Clipping. The Brush Clipping feature of the editor is used to "clip" a section off of a predetermined Brush. This is done by placing clip points on or around your brush that define the clipping point. To lay a clip point, hightlight the brush by clicking on it then left click on the nearest vertex point. Next highlight the clip point and CTRL + left click it to drag it into position. You need at least two clip points to clip a Brush. When you lay clip points, they are numbered according to the order they were placed. Clip points look like thumb tacks. Once the clip points are in place use the Clip Selected Brush or the Split Selected Brush button to perform clipping actions. Remember that BEFORE you execute clipping operations, perform a Transform Permanently! That pertains the the red builder brush as well as any added or subtracted Brushes.

    Clip Selected Brush. Let us use a cube as an example. Create a cube in a room. Line up the cube in all the viewports. Select one of the 2D viewports you want to work with. Click the Brush Clipping button. Next activate the cube brush by clicking on it. In the top viewport hold down Ctrl + Alt and right click on the are where you want to place the clip point (it looks like a thumb tack). Click on the vertex in the opposite corner to place the second clip marker. A line will now be drawn though the middle of the cube connected by the clip markers. The connecting line will have a small line in the middle pointing towards the area to be clipped off. This can be changed to the opposite direction by clicking the Flip Clipping Normal button. Finally click the Clip Selected Brush and now the Brush will be clipped. A 3D clip plane can be achieved by adding clip point in the side and front viewports.

    Split Selected Brush. Follow the same steps as you would when using the Clip Selected Brush feature. In this case you will be splitting the clipped brush into two different pieces.

    Flip Clipping Normal. This function will move the direction of the clip you are going to perform based on the direction of the small red line that is pictured below. That small red line will point towards the area to be clipped off.

    Delete Clip Markers. Used to delete all clip markers.

    Brushes:

    Build a cube. This will create a cube brush for you. If you right click on it, it will give you an option to go to cube properties. This will allow you to change the height, depth etc of the cube brush you will create.

    Build a Sphere. This is the same as the cube, but it will create a round ball shaped (well a sphere really) brush. Once again right click on it to alter the properties of the brush.

    Build a cylinder. This will create a cylinder for you, that you can use like any other brush.

    Build a cone. This will create a cone (rounded pyramid) that you can use like any other brush.

    Build a stair. This will create a straight flight of stairs. These stairs will not turn or curve as they go up.

    Build a spiral stair. This will create a rounded set of stairs that can be set to form a very tight spiral staircase.

    Build a curved stair. This will simply create a rounded set of stairs that are similar to the first set, but they curve around to a side when they have been built.

    Build a sheet. This creates a 2 dimensional sheet. It can be used for a VERY LARGE number of applications. One of the most common is to create a water plane. This tool does however require more practice then the other brushes, as it is not a 3D brush and can easily "wreck" a level. It should NOT (I can't stress this enough) be used to create walls and other solid shapes. (Well at least until you are quite familiar with the editor).

    Operations:

    Add brush to world. This button is used to "add" a brush to the world. Any brush can be added to the world, but make sure that you don't try to add something to a piece of the world that is already solid, as this can turn out quite nasty when playing the game or rebuilding...

    Subtract brush from world. This button will "carve" out the brush from your level. Do not try to subtract a brush from an area that has already been subtracted - as this won't work and can have adverse (bad) effects on your level.

    Brush intersection. This is the "intersect" button. It is used to change your brush. Say you have a "cube" brush, but only want to cut out half a cube from a solid wall. You could go through the cube properties and change the shape of your brush, or you could simply move the cube to where you want it to go and then press this button. This will make a new brush for you - but it will only be where the solid wall was before. It is also good for making complex objects into a single brush. Say you want to make a fireplace, and you want to use it in a few places - create it (bit by bit) and then place a cube brush over the top (so the cube {or whatever} encompasses the fireplace totally) and when you press this button, your new brush will be EXACTLY the same as what you created using many little bits.

    Brush deintersection. This does the opposite of what the intersect button does. It will select the parts of the brush that are in an area that is not solid - and create them into a new brush for you.

    Add Special Brush. This allows you to create "special" brushes to your map. These can be a wide range of things, such as windows, water levels, portals and the like. It is normally used in combination with the "sheet" brush.

    Add movable brush. This button will create a mover for you. It will use whatever brush you have currently selected. When using this brush however, make sure that the brush you have selected has NOT been stretched in any way, as it won't work properly...

    Viewing Modes:

    Show Selected Actors Only. This button will hide all Actors that are not selected. Good for isolating a few Brushes or Actors that are located in an area with many other objects.

    Hide Selected Actors. This button will hide any actor that is selected.

    Show All Actors. This button will make all actors visible in all of the viewports. Any hidden Actors will now be visible.

    Invert Selection. Clicking this button will invert the selection of current actors. Will select the exact opposite of what was selected before clicking this button.

    Change Camera Speed. Is the camera moving to slow for you? Click this button to scroll quicker through your level. The camera speed can also be decreased. Excellent for large maps.


Editor Tool Buttons

Editor 2.0 Header Buttons

    By: Brad 'BadDog' Streng

    bstrange@hmcltd.net

    Descriptions by:

    astro'

    astro@planetunreal.com

    UED Resource Lab

    Functions:

    New. This one is pretty self explanatory, it creates a new level.

    Open. This button is used to open an existing level from your Unreal/UT Maps folder. Any level with a .unr suffix can be opened.

    Save. This button will save the current level under it's current filename.

    Undo. This button is used to undo the last operation, or operations. You cannot undo operations made prior to rebuilding your level. Once a level has been rebuilt, you can only undo operations made after the rebuild.

    Redo. This will allow you to redo an operation if you click the undo button one to many times.

    Search for Actors. Use this button to find specific Actors in your level. Every Actor has a corresponding name associated with it as shown above. You can search by Name, Event, or Tag. Once the Actor is displayed on the left hand side under "Names" double click it and all the viewports will center on the Actor. Great for finding Actors in larger maps.

    Actor Class Browser. Use this button to browse different "Actors" which can be placed into your level. An Actor is any object you place into your map. Select your Actor, then right click in the 3D viewport and add the actor from the pop up menu.

    Group Browser. All Actors and Brushes can be managed by using the Group Bowser. Use this to easily select and modify a user defined group. Highlight a set of Actors you want to be grouped together in any of the viewports. Next click the Group Browser button. Next click the New Group button and name it. Finally click the Add Selected Actors to Group button. In the future you can activate that group of brushes by going to the Group Browser, selecting the group name then clicking the Select Actors in Group button.

    Music Browser. Use the Music Browser to select music to insert music into any level. Also has the ability to import music in many different formats as seen above. The onboard Galaxy Sound Viewport can handle all the above file types. Use ModPlug Tracker to make your own music! Unfortunately the Unreal Engine does not and probably will not support MP3's.

    Sound Browser. The Sound Browser is used to insert various sound effects to add sounds for a richer gaming experience. Make your own custom sounds and import them into your map. As long as they are a .wav file you are all set. Remember that .wav files can become very large. Avoid using large .wav files because the Unreal Engine will have a tough time with them. I have had a large .wav file not play at all. Very useful for importing custom sounds for lifts, doors, environments and the such.

    Texture Browser. The Texture Browser is used to apply textures to all surfaces in your level. You can also import your own images and create your own texture package. The current supported texture import specs are : PCX format, 256 colors. As quoted by Tim Sweeney: "Unreal texture dimensions may be any powers of two from 1 to 1024. Textures need not be square. For example, many of the textures in Unreal are 128x128, 256x128, and 256x256. Unreal's software rendering code supports textures of any size from 1x1 up to 1024x1024." There are a few ways you can texture and object. Highlight the surface you want to texture then click on a texture in the texture browser. That will add the texture to the surface you highlighted. OR, you can select the texture you want to use in the texture browser then hold down the ALT key on your keyboard and right click the surface in the 3D viewport. This method is quick way to apply textures. Also an excellent way to REMOVE a texture from a map is to highlight the texture in the texture browser then press "Q" on your keyboard. Then rebuild the map and save. That hint should save you some woes down the road.

    Mesh Browser. Objects within the Unreal Engine use a Mesh to provide a skin and/or animation for a graphical representation. All meshes can be displayed through the Mesh Browser.

    2D Shape Editor. One of the most important editors used for creating complex and non-standard Brushes. The 2D shaper has evolved greatly with UnrealED2.

    Unreal Script Editor. Use this editor to manipulate scripts already used in the Unreal Engine or create your own from scratch. Every actor in your level can be modified through the use of scripts. You can even create your own classes from scratch. If you want to dabble in code, this is the place to start.

    Go to Chimeric to get started with UScript.

    Actor Properties. Another extremely important interface for configuring the advanced properties of an Actor or Brush. Notice all of the configurable aspects of this example actor. Tweaking these settings is where it is at.

    Example usage: Let us use a light as an example. This is the interface you would use to change the color, radius and brightness of a light - just to name a few.

    Surface Properties. Used to configure the properties of a surface. Surfaces can be scaled, panned and rotated using this interface. All Flags for textures can be modified as well. In order to see changes made to a flag on a texture you must rebuild first. Highlight a surface (or surfaces) in the 3D viewport then click the Surface Properties button. You can also right click on a surface then choose properties from the pop up menu.

    Build Geometry. This button will only rebuild the geometry. Use this to rebuild quickly and save time by avoiding a sometimes lengthy rebuild process on larger maps.

    Build Lighting. This button will rebuild the lighting only.

    Build Paths. This button builds the Path Node network. Use the Actor Class Browser to add path nodes for the Bot AI. In order for bots to function properly you must lay path nodes then build the paths. Otherwise the bots will stand in place - NOT a good thing

    Build All. This button builds all as defined by the current build settings

    Build Options.

    Use this button to access the interface for selecting the various build options: Lighting, BSP, Geometry and Paths. The Create Path Network button will prompt the editor to automatically add in path nodes for the bots. The editor will make it best guess as at laying the Nodes. This is not the best method for Path Noding and usually needs a lot of debugging. The Stats tab will give in in depth information including BSP, Zones, Lights and Geometry.

    Thanks to Warren Marshall for the following explanations:

    Portals Cut All: Defines how aggressively portal brushes cut the BSP. If you find that water zones and such aren't getting created properly, try moving this slider up a little. Most of the time you don't have to touch it ...

    Balance Tree: You can choose how you want the BSP compiler to prioritize the polys...
    less cuts or more balance in the tree. The default value is fine 99.99999% of the time ...

    Build Visibility Zones: Do not change this setting!

    Play Level. This will play your map straight out of the editor. The editor automatically saves your map before playing under the name "autoplay" (without an extension). This in essence creates a backup of your map in case of disaster.


BB Drac - BB Drac - Unreal Tournament UED2 guide Interface

The Interface Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Window views:
When you first start UED2 four windows display everything
you create.
The top left is from above, the top right is from the front.
Bottom right is from the side and the one to the left is 3D view.

 New, Open, Save:
Button
Start a new map from scratch, open a saved map and save the current map.

 Undo, Redo:
Button
Undo or redo your last actions.
You may undo or redo more than one action but I don't know how many.

 Camera mode:
Button
This is the default mode and you will only move selected object.
(All mode buttons is associated with the CTRL. Read the Object handler tutorial.)

 Vertex editing:
Button
While active you can highlight a vertex by pressing the Right mouse button on it.
Then simply move it (by holding ctrl and the left mouse button).
(You are actually able to do this any way, but using the ALT instead).

 Scale mode:
Button
You will now resize selected object using the CTRL button.
(All mode buttons is associated with the CTRL. Read the Object handler tutorial.)

 Rotate mode:
Button
Rotate selected object instead of moving it, using the CTRL button.
(All mode buttons is associated with the CTRL. Read the Object handler tutorial.)

 Texture pan:
Button
This mode is a bit different. When you hold the CTRL button after selected a surface
you pan the texture. Left mouse button for horizontal and right mouse button for vertical.
(May also be done using the properties of a texture).
(All mode buttons is associated with the CTRL. Read the Object handler tutorial.)

 Texture rotate:
Button
Rotate a selected texture while holding the CTRL and Left mouse button.
(All mode buttons is associated with the CTRL. Read the Object handler tutorial.)

 Change camera speed:
Button
This will change the speed you move around in each of the views.

 Add:
Button
Adds mass to the world (equal to the size and shape of your brush/builder tool).

Subtract:
Button
Removes mass from the world (equal to the size and shape of your brush/builder tool).

 Intersect:
Button
This is used to remove part of the brush that exist in open area.

 Deintersect:
Button
Works the same way as Intersect but removes parts of the brush that overlap into filled areas.

 Add special brush:
Button
Used to add Invisible collision hulls, zone portals and more.

 Add mover brush:
Button
When creating doors, elevators or other moving walls and like this is used.

 Show selected actors only:
Button
Will hide all other actors except the ones you have selected/highlighted.

 Hide selected actors:
Button
Hides all currently selected/highlighted actors.

 Show all actors:
Button
This resets any hide/show actors and shows everything again.

 Invert selection:
Button
Deselects your currently selected actors and selects everything else.

 Clip selected brushes:
Button
Don't know how this works.

 Split selected brushes:
Button
Don't know how this works.

 Flip clipping:
Button
Don't know how this works.

 Delete clipping markers:
Button
Don't know how this works.

 Cube brush:
Button
Create a brush shaped as a cube with the given properties.
(Right mouse button to enter these values).

Height: Z axis size of the cube.
Width: Y axis size of the cube.
Breadth: X axis size of the cube.
WallThinkness: Differance between inner and outer edges if hollow=True.
GroupName: Used if you want to croup brushes.
Hollow: Brush will have an inner room, size is [brushsize]-WallThinkness.
Tessellated: Create a more vertex edit friendly brush (excludes Hollow).

Sheet brush:
Button
Create a brush shaped as a sheet with the given properties.
(Right mouse button to enter these values).

Height: Z axis size of the sheet (Axis=horizontal).
Width: Y axis size of the sheet (Axis=Horizontal).
Axis: Direction of sheet, Horizontal, X-Axis or Y-Axis.
GroupName: Used if you want to croup brushes.

Cylinder brush:
Button
Create a brush shaped as a cylinder with the given properties.
(Right mouse button to enter these values).

Height: Z axis size of the cylinder.
OuterRadius: X and Y axis circle size (diameter=radiusx2).
InnerRadius: X and Y axis circle size if hollow=True.
Sides: Amount of faces to the cylinder.
GroupName: Used if you want to croup brushes.
AlignToSide: If radius should apply to point or flat side.
Hollow: Creates a tube (InnerRadius < OuterRadius).

Cone brush:
Button
Create a brush shaped as a cone with the given properties.
(Right mouse button to enter these values).

Height: Z axis size of the cone.
OuterRadius: X and Y axis circle size (diameter=radiusx2).
InnerRadius: X and Y axis circle size if hollow=True.
Sides: Amount of faces to the cylinder.
GroupName: Used if you want to croup brushes.
AlignToSide: If radius should apply to point or flat side.
Hollow: Creates a carved cone (InnerRadius < OuterRadius).

Sphere brush:
Button
Create a brush sphere as a sheet with the given properties.
(Right mouse button to enter these values).

Radius: Size of sphere (diameter=radiusx2).
SphereExtrapolation: Complexity of sphere.
GroupName: Used if you want to croup brushes.

Curved stair brush:
Button
Create a brush shaped as a curved staircase with the given properties.
(Right mouse button to enter these values).

InnerRadius: Distance from center point to inner side of stairs.
StepHeight: Z axis distance between steps (total height = NumSteps * StepHeight).
StepWidth: Circular width of steps (OuterRadius = InnerRadius + StepWidth).
AngleOfCurve: Total stairs length (90 = 1/4 circle)
NumSteps: Total amount of steps (in AngleOfCurve).
AddToFirstStep: Extra height added to first step (StepHeight + AddToFirstStep).
GroupName: Used if you want to croup brushes.
CounterClockwise: Base direction of stair.

Spiral stair brush:
Button
Create a brush shaped as a spiral staircase with the given properties.
(Right mouse button to enter these values).

InnerRadius: Distance from center point to inner side of stairs.
StepWidth: Circular width of steps (OuterRadius = InnerRadius + StepWidth).
StepHeight: Z axis distance between steps.
StepThinkness: Base size of step.
NumStepsPer360: Amount of steps to complete a circle.
NumSteps: Total amount of steps.
GroupName: Used if you want to croup brushes.
SlopedCeiling: If underside should slope upwards or not.
SlopedFloor: If floor should slope downwards or not (creates spiral ramp/slope).
CounterClockwise: Base direction of stair.

Linear stair brush:
Button
Create a brush shaped as a linear staircase with the given properties.
(Right mouse button to enter these values).

StepLength: X axis size of steps (total length = NumSteps * StepLenght).
StepHeight: Z axis distance between steps (total height = NumSteps * StepHeight).
StepWidth: Y axis size of steps.
NumSteps: Total amount of steps.
AddToFirstStep: Extra height added to first step (StepHeight + AddToFirstStep).
GroupName: Used if you want to croup brushes.

Terrain brush:
Button
Used to create outdoor enviroment. Using this instead of manually doing it will
reduce BSP cuts.
(Right mouse button to enter these values).

Height: Z axis size of the cube.
Width: Y axis size of the cube.
Breadth: X axis size of the cube.
WidthSegments: Amount of 'detail' in the X axis.
DepthSegments: Amount of 'detail' in the Y axis.
GroupName: Used if you want to croup brushes.

Volumetric brush:
Button
Multiple sheet builder (volumetric). Used to create flames, chains etc.
(Right mouse button to enter these values).

Height: Z axis size of the sheets.
Radius: X and Y Size of sheets (diameter=radiusx2).
NumSheets: Amount of sheets.
GroupName: Used if you want to croup brushes.

Search for actor:
Button
Will show you a complete list of all actors and the possibility to filter out.

Texture browser:
Button
Opens a window to show available textures.

Actor browser:
Button
Opens a window to show available actors.

Sound browser:
Button
Opens a window to show available sound effects.

Music browser:
Button
Opens a window to show available songs.

2D shape editor, Mesh viewer, Script editor:
Button
The first button is the 2D shape editor.
Use this to create shapes that you are unable to use predefined brushes tools for.

The second button is a mesh viewer. It will show you how a mesh looks and is animated.

Third button is the script editor. Change allready existing or create new.

Actor and Surface properties:
Button
The buttons will open the properties window for either actor or surface.

Build Geo, Light, Path and Options:
Button
The first button will rebuild the geometry but not add lightning.
The second button will add correct lighting to your design.
Third button will simply rebuild the AI paths.
Fourth button opens the rebuild options window.

Play map:
Button
Press this button to test play your map.

Realtime view:
Button
Turns on/off realtime update. (Can be resource demanding).

View Top, Front, Side:
Button
Changes your window view to 2D. Either top, front or side.

View Perspective:
Button
Changes your window view to 3D and wireframe mode.

View Texture usage:
Button
Changes your window view to 3D and texture usage. Each texture will have it's own color.

View BSP:
Button
Changes your window view to 3D and to BSP cuts.

View Textured:
Button
Changes your window view to 3D but without lightning added.

View Dynamic light:
Button
Changes your window view to 3D and as the level will look.

View Zone/Portal:
Button
Changes your window view to 3D and how your design is zoned.
(Also show BSP cuts).

ViewPort options:
By pressing right mouse button on the top bar in each window you may select different
view options.
It will only affect the window you selected it for.

Mode is the different 2D and 3D view modes.
View, Show active brush: Disables/Enables view of the builder brush.
View, Show moving brushes: Disables/Enables view of mover brushes.
View, Show paths: Disables/Enables view of the navigation network.
Actors, Full Actor View: Will show all actors that have DrawType "DT_sprite".
Actors, Icon View: Will show all actors that have any DrawType.
Actors, Radii View: Will show collision and affected radius of actors.
Actors, Hide All Actors: Will not draw any actor in the viewport.
Window, 16bit: Set the color depth of the viewport.
Window, 32bit: Set the color depth of the viewport.
To the end you are able to shift between different render modes.
(Don't know if there is any other than Software or Direct3D).


BB Drac - Unreal Tournament UED2 guide Brush handling

Brush Handling

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

When UED2 starts up you always face north, along the X axis.
In top view, the X axis run from left to right (-X to +X).
The Y axis goes from top to bottom (-Y to +Y).
The Z axis runs from the "depth" towards you (-Z to +Z)
In the front and side view Z axis run from bottom
to top (-Z to +Z)
In the properties under "Movement" you have "Location".
This is the precise location of your objects.

 Move:
Hold down either shift or ctrl and the left mousebutton.
(Shift locks the view to the object).
To move object in 3D view you hold either shift and ctrl.
Left mousebutton to move it on the X axis.
Right mouse button to move it on the Y axis and both
mousebuttons for the Z axis.

 Rotate:
Hold down either shift or ctrl and the right mousebutton.
(Shift locks the view to the object).
The angle you rotate depends on the view, unless you change to rotate mode.

To rotate objects more than one angle or in 3D view you need to change
mode to rotate (More info. on buttons in the interface guide).
Hold ctrl and the left mouse button to rotate on XZ.
Right mousebutton for XY and both buttons for YZ.

 Size:
To modify the size of objects you need to change to scale mode.
(More info. on buttons in the interface guide).
The direction you resize the object depends on the view.
Hold ctrl and the Left mousebutton to resize in one direction
and the right mousebutton for the other direction.
Both mousebuttons for a dynamic resize (both directions).

In 3D view resize is a bit different.
Hold ctrl and left mousebutton to change size on the X axis.
Ctrl and right mousebutton to change size on the Y axis and
both mousebuttons for the Z axis.

 Vertex editing:
A vertex is one of the corners in a brush.
To move them around, mark one of them, hold the ALT and left mouse button
and move the mouse around.
You do not need to change to "Vertex editing" mode to do this so just
ignore this button.

I strongly suggest you do vertex editing in one of the 2D views.
The 3D view is very difficult to use.
Just make sure that two points doesn't merge because you are
unable to split them again.
Also make sure that one poly/side of the brush isn't lost or
the editor will crash.
It is important that your poly/side of the brush is flat and not
bent or the texture will look weird, almost as if it move around.
(UT does not support bent textures/walls).
To change vertex snap on/off, toggle the button left of the grid setting.

 Important note:
When you have rotated and/or scaled a brush it will stay that size.
This means that if you rescaled a 256x256x256 brush/builder tool it
will not return to it's original size if you recreate a builder brush.
To do that, you need to reset the brush.
Press the right mouse button on the brush and select "Reset".

 Brush select / view:
If you hold down CTRL, ALT and the left mousebutton
you can drag-select multiple brushes.
Use this to hide or delete lots of objects at once.

 Right mouse button options:
If you press the right mouse button on a brush you are able to
select different options.

 Movers, this option lets you change current keyframe and
show the mover polys if you have patch 4.36.
(Only work on mover brushes).
 Reset, will reset the brush to its original state in
selected option or all of them.
 Transform, sets the brush to fixed shape.
Mirror [any] will flip the brush while transform permanently
will set the current scaling/rotation to the bush.
 Order, set the order of the brush to either first or last.
 Polygons, will change or create the brush from the selected
option.
Polygons to brush will take the current slected brush and duplicate
it to the builder brush.
Polygons from brush will move the current brush and force it
to the shape, size and location of the builder brush.
 Solidity, changes the current state of any added brush to
solid, semi-solid or non-solid.
 CSG, will change the brush to additiv or subtractive.
 Select all Brush, will highlight all brushes.
 Select all, will highlight brushes and actors.
 Select none, deselect all selected objects.
 select brushes, select more specific types of brushes.
 Duplicate, creates an identical object of the selected object.


Getting Started

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Where do I get UnrealEd 2.0
It it found within patch 420 or later for Unreal Tournament. For some download places check http://unreal.epicgames.com and http://www.unrealtournament.com
What are the system requirements
They are pretty much the same as the system requirements of UT. I've got it running on a AMD K2-400 with 128MB RAM (although I've upgraded to 256MB recently and the memory does help!)

What are the file formats UnrealEd uses

There are a lot of file formats that UnrealEd uses for different things. Most are dedicated Unreal file formats for music, maps (unr), textures (utx) etc. Below are some of the different external formats that you can use with UnrealEd:

  1. WAV
    Used for sound files
  2. S3M
    Used for music files
  3. PCX
    Used for textures, remember that for Unreal the PCX files must be 256 colors, PCX can be higher than this so check! They must also have sides based on powers of 2, so a side must be 2 pixels, 4, 8, 32, 1024 etc. Direct3D doesn't handle textures bigger than 512x512 well.
  4. DXF
    Autocad drawing exchange format. You can use this format to import brush shapes to complex to create in UnrealEd. I haven't played with this much but some programs don't appear to create 'nice' dxf files


The Buttons of Unrealed 2

The Buttons of Unrealed 2.0

By: astro

astro@planetunreal.com

UED Resource Lab

The Buttons of Unrealed 2.0 Part One Revision Two

Below is a picture and brief description of each button in the editor.

Browsers, Editing, Properties, an d Build Options:

Search for Actors:

Search with me

Use this button to find specific Actors in your level. Every Actor has a corresponding name associated with it as shown above. You can search by Name, Event, or Tag. Once the Actor is displayed on the left hand side under "Names" double click it and all the viewports will center on the Actor. Great for finding Actors in larger maps.

Actor Class Browser:

Browse and select an Actor type to use

Use this button to browse different "Actors" which can be placed into your level. An Actor is any object you place into your map. Select your Actor, then right click in the 3D viewport and add the actor from the pop up menu.

Group Browser:

Create groups of brushes or actors with the group browser

All Actors and Brushes can be managed by using the Group Bowser. Use this to easily select and modify a user defined group. Highlight a set of Actors you want to be grouped together in any of the viewports. Next click the Group Browser button. Next click the New Group button and name it. Finally click the Add Selected Actors to Group button. In the future you can activate that group of brushes by going to the Group Browser, selecting the group name then clicking the Select Actors in Group button.

Music Browser:

Select your track here Use ModPlug Tracker to make your own music for your levels

Use the Music Browser to select music to insert music into any level. Also has the ability to import music in many different formats as seen above. The onboard Galaxy Sound Viewport can handle all the above file types. Use ModPlug Tracker to make your own music! Unfortunately the Unreal Engine does not and probably will not support MP3's.

Sound Browser:

Access and use sounds here Import WAV files

The Sound Browser is used to insert various sound effects to add sounds for a richer gaming experience. Make your own custom sounds and import them into your map. As long as they are a .wav file you are all set. Remember that .wav files can become very large. Avoid using large .wav files because the Unreal Engine will have a tough time with them. I have had a large .wav file not play at all.

Very usful for importing custom sounds for lifts, doors, enviroments and the such.

Texture Browser:

Pick your poison Import .PCX files

The Texture Browser is used to apply textures to all surfaces in your level. You can also import your own images and create your own texture package. The current supported texture import specs are : PCX format, 256 colors. As quoted by Tim Sweeney: Unreal texture dimensions may be any powers of two from 1 to 1024. Textures need not be square. For example, many of the textures in Unreal are 128x128, 256x128, and 256x256. Unreal's software rendering code supports textures of any size from 1x1 up to 1024x1024. There are a few ways you can texture and object. Highlight the surface you want to texture then click on a texture in the texture browser. That will add the texture to the surface you highlighted. OR, you can select the texture you want to use in the texture browser then hold down the ALT key on your keyboard and right click the surface in the 3D viewport. This method is quick way to apply textures. Also an excellent way to REMOVE a texture from a map is to highlight the texture in the texture browser then press "Q" on your keyboard. Then rebuild the map and save. That hint should save you some woes down the road.

Mesh Browser:

Mesh viewer can view in game animations

Objects within the Unreal Engine use a Mesh to provide a skin and/or animation for a graphical representation. All meshes can be displayed through the Mesh Browser.

2D Shape Editor:

Master me! One of the most important editors used for creating complex and non-standard Brushes. The 2D shaper has evolved greatly with UnrealED2.

Unreal Script Editor:

Code and more code.... :)

Use this editor to manipulate scripts already used in the Unreal Engine or create your own from scratch. Every actor in your level can be modified through the use of scripts. You can even create your own classes from scratch. If you want to dabble in code, this is the place to start.

Goto Chimeric to get started with UScript.

Actor Properties:

Everything can be configured

Another extremely important interface for configuring the advanced properties of an Actor or Brush. Notice all of the configurable aspects of this example actor. Tweaking these settings is where it is at.

Example usage: Let us use a light as an example. This is the interface you would use to change the color, radius and brightness of a light - just to name a few.

Surface Properties:

Align your textures Special properties for textures

Used to configure the properties of a surface. Surfaces can be scaled, panned and rotated using this interface. All Flags for textures can be modified as well. In order to see changes made to a flag on a texture you must rebuild first. Highlight a surface (or surfaces) in the 3D viewport then click the Surface Properties button. You can also right click on a surface then choose properties from the pop up menu.

Build Geometry: Will only rebuild the geometry. Use this to rebuild quickly and save time by avoiding a sometimes lengthy rebuild process on larger maps.

Build Lighting: Builds lighting only.

Build Paths: Builds the Path Node network. Use the Actor Class Browser to add path nodes for the Bot AI. In order for bots to function properly you must lay path nodes then build the paths. Otherwise the bots will stand in place - NOT a good thing

Build All: Builds all as defined by the current build settings

Build Options:

Dont forget to build

Use this button to access the interface for selecting the various build options: Lighting, BSP, Geometry and Paths. The Create Path Network button will prompt the editor to automatically add in path nodes for the bots. The editor will make it best guess as at laying the Nodes. This is not the best method for Path Noding and usually needs a lot of debugging. The Stats tab will give in in depth information including BSP, Zones, Lights and Geometry.

Thanks to Warren Marshall for the following explainations:

Portals Cut All: Defines how aggressively portal brushes cut the BSP. If you find that water zones and such aren't getting created properly, try moving this slider up a little. Most of the time you don't have to touch it ...

Balance Tree: You can choose how you want the BSP compiler to prioritize the polys...
less cuts or more balance in the tree. The default value is fine 99.99999% of the time ...

Build Visibility Zones: Do not change this setting!

Play Map: This will play your map straight out of the editor. The editor automatically saves your map before playing under the name "autoplay" (without an extension). This in essence creates a backup of your map in case of disaster.


The Buttons of Unrealed 2

The Buttons of Unrealed 2.0 Part 2

By: astro

astro@planetunreal.com

UED Resource Lab

The Buttons of Unrealed 2.0 Part 2 Revision One

Below is a picture and brief description of each button in the editor.

Modes, Clipping, Builders, CSG (Constructive Solid Geometry), and Miscellaneous:

Camera: When the editor loads Camera mode is the default mode.

Vertex Editing: Vertex Editing is used to manipulate the points, or Vertices of a Brush. After selecting the Vertex Editing button, you will notice the pointer icon has changed. Click on the Brush you wish to work with. The vertices are now grey. Hold down Ctrl+Alt and drag a selection box around the points you wish to move. Once you have selected the points they will turn white. Hold down Ctrl then left click to move the points to a new position. If you are using the red builder brush, perform a Transform Permanently BEFORE you add or subtract the brush. If it is an existing brush, right click on it and perform a Transform Permanently then build. You can not edit a Brush that has been Transformed Permanently. If the Brush is going to be in an area where a player wont touch it you can make the Brush semisolid. This in some cases can cut down on BSP holes/cuts and speed up the game.

Brush Scaling: All Brushes can be scaled. Scaling can increase or decrease the size of a Brush on the fly. One disadvantage of scaling is you do not have control over exact measurements. Click the Brush Scaling button and again the pointer icon will change. Left click a point on the desired Brush to activate that vertex. Ctrl + either right or left click will scale to Brush in a different direction. The active side that is being scaled depends on the vertex you choose to start with. When finished, perform a Transform Permanently.

Brush Rotate: With this button activated, you can rotate the brush using Ctrl + left click and Ctrl + right click. Very useful for moving a brush into position.

Texture Pan: With this button activated, you can pan a texture using Ctrl + left click and Ctrl + right click. Very useful for aligning a texture that wont line up using the surface properties dialog box.

Texture Rotate: Highlight the texture in the 3D viewport you wish to rotate. Now you can left OR right click while holding down Ctrl and the texture will rotate

Brush Clipping: The Brush Clipping feature of the editor is used to "clip" a section off of a predetermined Brush. This is done by placing clip points on or around your brush that define the clipping point. To lay a clip point, hightlight the brush by clicking on it then left click on the nearest vertex point. Next highlight the clip point and CTRL + left click it to drag it into position. You need at least two clip points to clip a Brush. When you lay clip points, they are numbered according to the order they were placed. Clip points look like thumb tacks. Once the clip points are in place use the Clip Selected Brush or the Split Selected Brush button to perform clipping actions. Remember that BEFORE you execute clipping operations, perform a Transform Permanently! That pertains the the red builder brush as well as any added or subtracted Brushes.

Clip Selected Brush: Let us use a cube as an example. Create a cube in a room. Line up the cube in all the viewports. Select one of the 2D viewports you want to work with. Click the Brush Clipping button. Next activate the cube brush by clicking on it. In the top viewport hold down Ctrl + Alt and right click on the are where you want to place the clip point (it looks like a thumb tack). Click on the vertex in the opposite corner to place the second clip marker. A line will now be drawn though the middle of the cube connected by the clip markers. The connecting line will have a small line in the middle pointing towards the area to be clipped off. This can be changed to the opposite direction by clicking the Flip Clipping Normal button. Finally click the Clip Selected Brush and now the Brush will be clipped. A 3D clip plane can be achieved by adding clip point in the side and front viewports.

Split Selected Brush: Follow the same steps as you would when using the Clip Selected Brush feature. In this case you will be splitting the clipped brush into two different pieces.

Flip Clipping Normal:

This function will move the direction of the clip you are going to perform based on the direction of the small red line that is pictured above. That small red line will point towards the area to be clipped off.

Delete Clipping Markers: Used to delete all clip markers.

Build Cube:

The Cube button brings up the CubeBuilder dialog box which enables you to set the parameters of the cube you are going to build. These settings are displayed through the use of the red builder brush seen in any of the viewports. The size of the red builder brush will change if you change any of the dimensions in this interface (The same applies to all the other build buttons as well). You can change the value of Hollow to True which will make the cube hollow. The thickness of the walls depends on the value set in Wall Thickness. If Tessellated is set to True you will have more vertices in the cube which makes more Vertex Editing options available.

Build Sheet:

Sheet Builder is used to build sheets for use in Portals, Water, Lava, Glass, etc. Set your desired dimensions and you are ready to go. The sheet builder works hand in hand with the Add Special button. Just a note that using a sheet brush in certain instances can cause BSP errors and the dreaded HOM (Hall Of Mirrors) effect. Take care in using sheet brushes and lining them up in your map. If you get any side effects from the use of a sheet brush, try realigning it and rebuilding. In a worst case scenario you can delete the brush and add a new one.

Build Cylinder:

Builds a Cylinder. Remember that the more sides you define creates more polys for the engine to render and can slow down the map. If Hollow is set to True the Cylinder will be hollow in the middle and is directly effected by the InnerRadius setting.

Build Cone:

Builds a Cone. CapHeight and InnerRadius can only be modified when Hollow is set to True. CapHeight is how tall the hollowed center is in relation to the overall Height of the cone.

Build Sphere:

Use the Tetrahedron Builder to build a sphere. The default settings for the Sphere will create the shape of a diamond. Use the SphereExtrapolation setting to add vertices to the Sphere which makes it more rounded. DO NOT use a setting higher than 5! Doing so will create too many vertices and will drastically slow down your map. I found this out the hard way. I pushed it and used a value of 25 and the editor did not like it at all (I did not even attempt to run it in the game).

Build Curved Staircase:

This button will create a curved staircase. The InnerRadius setting will make the staircase larger or smaller depending on the setting. For a small tight staircase, lower this setting. For a larger staircase increase this setting. StepHeight is the height of the staircase. Do not set to over 32 or a player will not be able to get up the stairs without jumping or Translocating. StepWidth will determine how wide the steps are. AngleCurve setting will determine the curve rate of the staircase. NumSteps determines the amount of steps from bottom to top. AddToFirstStep will extrude the lower part of the staircase to make it taller. This effects every step on the staircase and not just the first one as the name implies. CounterClockwise setting will change the direction of the staircase.

Build Spiral Staircase:

Build a Spiral Staircase. Keep SlopedCeiling set to True. Change the SlopedFloor setting to True if you want the steps to be smooth and flow into each other.

Build Linear Staircase:

Creates a simple Linear Staircase. This interface is self explanatory :) Change the AddToFirstStep setting if you want to add a bottom layer to the entire staircase starting at the fist step.

Terrain Builder Brush:

Use the Terrain Brush to create environments such as mountains. The WidthSegments and DepthSegments button will add vertices that you can Vertex Edit. This is a primitive tool. Try 3D StudioMax and this tutorial for making adanced terrain.

Volumetric:

The Volumetric Builder is used to make torches and effects. Use this in conjunction with the Add Special button.

Add Brush to World: This button is used to build a shape defined by the red builder brush. Once you have your red builder brush sized the way you want it use this button to add it to your level. Use the Add Brush to World button only when adding to an existing room. NEVER add a brush when in the "void" (the area in any of the viewports which is empty space).

Subtract Brush from World: This button is also used to build a shape defined by the red builder brush.Use this button when creating a room for the first time. What this does is subtract or take a bite out of the "void" area and replace it with whatever it is you are subtracting. ONLY use the Subtract Brush from World button when in the "void".

Intersect: Used in the creation of a complex brush. Take the red builder brush and completely surround the brushes you wish to intersect. Click the intersect button (If making a mover, next right click the builder brush and perform a Polygons>To Brush function... This will copy all the textures from the target brushes to the red builder brush). Now all the brushes are transferred into the red builder brush and can be added or subtracted as one brush but retain the individual faces which can all be textured differently.

Deintersect: Before After

The process of Deintersection is used with the red builder brush. In the picture above one half of the red builder brush is in the "void" (B ) and the other half is in a room (A). If you deintersect the Brush, the part that was in the void will be cut off. This also applies to Added Brushes.

Add Special:

Use the Add Special button to build brushes with special properties. Above is a list of the different types of special brushes. Once your red builder brush is ready to be built click the Add Special button (Make sure you have your texture selected in the Texture Browser ). Refer to this tutorial for an example of using the Add Special function.

Add Mover:

Movers are Actors that use KeyFrames to move from one position to another. Right clicking on the Add Mover button will display the pop up menu pictured above and list Mover types. Once the mover is built, right click on the brush and select Movers. Another windows will slide out. This is where you set the Key Frames for the mover.

Let us use a simple mover that will act like an elevator that moves from the ground up then back down again:

Key 1 is the position the mover will start in. Key 0 is the next position the mover will move to. These settings are part of the process in gettings Movers to work. I think this deserves a tutorial in its self so we will stop here :)

Show Selected Actors Only: This button will hide all Actors that are not selected. Good for isolating a few Brushes or Actors that are located in an area with many other objects.

Hide Selected Actrors: Will hide any Actor that is selected.

Show All Actors: This button will make all actors visible in all of the viewports. Any hidden Actors will now be visible.

Invert Selection: Clicking this button will invert the selection of current actors. Will select the exact opposite of what was selected before clicking this button.

Change Camera Speed: Is the camera moving to slow for you? Click this button to scroll quicker through your level. The camera speed can also be decreased. Excellent for large maps.


The Toolbox

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Contents:
[ MODES ] [ CSG ] [ FILTERS ] [ CLIPPING ] [ BUILDERS ]

THE MODES
 | Camera Mode 'Normal' mode. Left click and move the mouse to move around. Left and Right click and move up and down to zoom in and out. Ctrl+Left Mouse moves the currently selected brush or the builder brush Ctrl+Right Mouse rotate the currently selected brush. Shift+Left Mouse move everything apart from the current brush.
 | Scale Mode This allows scaling of the currently selected brush, horizantally with Ctrl+Left Mouse button, and vertically with Ctrl+Right Mouse Button
 | Rotate Mode
 | Texture Pan Mode
 | Texture Rotate Mdoe
 | Vertex Editing Mode The newest kid on the Block.
 | Enters you into Clipping Mode When in clipping mode CTRL+Right Mouse places a clipping point.
CLIPPING
 | Clip Selected Brushes After placing the clipping markers, select the brush you wish to clip, and then press this button. This will delete half of the currently selected brush, usually the side away from the 'normal'
 | Split Selected Brushes This will split the selected brush into two brushes. For this operation the position of the normal is unimportant.
 | Flip Clipping Normal This will flip the side of the clipping markers the normal is on.
 | Delete Clipping Markers Deletes all the clipping markers off the screen. Adding a fourth clipping marker has the same effect.
BUILDERS (Right click builders for size options!)
 | Cube Please, do I need to say more!
 | Sheet Note: sheets NEVER collide with players, use thin cubes instead, or place a invisible collision hull behind a sheet. Sheets start out as one-sided, so if they look black then either rotate them or make them two sided (surface properties).
 | Cylinder
 | Cone Note: a 3 sided cone is a pyramid!
 | Tetrahedran (Sphere)
 | Curved Staircase
 | Spiral Staircase
 | Linear Staircase STEPS!
 | BSP Based Terrain
 | Build Volumetric shapes, such as chains and torches (i.e. 2 sheets crossed over).
CSG
 | Add Brush This adds the current builder brush to the world geometry
 | Subtract Brush This subtracts the current builder brush from the world geometry
 | Intersect This intersects the builder brush with the current world geometry, for example if you have subtracted a room from the world, then placing the builder brush half in the room and half in the wall, this would leave the bit in the wall.
 | De-Intersect The opposite of above, this would leave the half in the room.
 | Add Special Brush This is used to add all the special types of brushes to the map including zone portals, invisible collision hulls, water and masked walls.
 | Add Mover This adds the current brush as a mover. Right click for the different types of movers. Check out my Mover reference for more details about movers.
FILTERS
 | Show Selected Actors Only This will hide all actors apart from those currently selected
 | Hide Selected Actors This will hide the currently selected actors
 | Show All Actors This will show all actors
 | Invert Selection This will invert the above selection, can be useful if you start by hiding most of the actors you actually want to work on so you can see more clearly, then hide some more etc until all the ones you wanted are hidden, then flip this switch.
 | Change Camera Speed Change camera move speed from very slow, to medium, to CliffyB style!


The Menubar

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Contents:
[ Text Menubar ] [ Icon Menubar ]
Text Menubar
  • File:
    • New - new font, level, script object or texture KEY - CTRL+N SHORTCUT KEY CONFLICT
    • Open - open a map KEY - CTRL+O
    • Save - save current map KEY - CTRL+L !!! NOTE, NOT CTRL+S !!!
    • Save As - change the save name of the current map
    • Import - Import Unreal Text file (.t3d) (When importing you should always pre-load all texture files used by the file)
    • Export - Export .t3d file
  • Edit:
    • Undo - Undo last action, note that a clip is actually 2 actions, so undo twice KEY - CTRL+Z
    • Redo - redo the last action you undid! KEY - CTRL+Y
    • Search for Actor - search the current level for actors, you can dynamically filter on Name (which is the object class, followed by a number) the event field or the tag field. Double clicking on the name of the object moves all views to center on that actor.
    • Cut - copies the selected brush or actor to the clipboard and then deletes it. Just out of interest I tried to copy and paste the active (builder) brush and got for my troubles a none-add, none-subtract brush, very bizarre! KEY - CTRL+X
    • Copy - copies the current brush or actor to the clipboard KEY - CTRL+C
    • Paste - pastes the clipboard KEY - CTRL+V
    • Duplicate - makes a duplicate of the currently selected brush or actor (or plural!) KEY - CTRL+W
    • Delete - deleted the currently selected brushes or actors KEY - DEL
    • Select None - de-selects all actors and brushes KEY - SHFT+Z
    • Select All Actors - selects all actors KEY - SHFT+A
    • Select All Surfaces - moves from actor/brush selection to surface selection and selects all surfaces in the level KEY - SHFT+S
    • Select Surfaces ->
      • Matching Groups - CRASHES UNREALED! DO NOT USE KEY - SHFT+G
      • Matching Items - Appears to do the same as Matching Brush?
      • Matching Brush - selects all the surfaces of any brushes with currently selected surfaces
      • Matching Texture - selects all the surfaces the same as any currently selected textures.
      • All Adjacent - selects all adjacent surfaces, just keeps going! KEY - SHFT+J
      • Adjacent Coplanars - selects surfaces which are adjacent and in the same plane and size (e.g. for a wall the 2 surfaces must be in parrallel and where they meet be exactly the same size) KEY - SHFT+C
      • Adjacent Walls - will select all vertical surfaces which connect with the current surface KEY - SHFT+W
      • Adjacent Floor/Ceilings - selects all the horizantal surfaces which select with the current one. If the current surface is a wall then both floor and ceiling will be selected. KEY - SHFT+F
      • Adjacent Slants - not sure, oh and there is a shortcut key conflict, as it says this is SHFT+S, which is actually select all surfaces! SHORTCUT KEY CONFLICT
      • Reverse - reverses the current surface selection level wide. KEY - SHFT+Q
      • Memorize Set - stores the currently selected surfaces in memory KEY - SHFT+M
      • Recall Memory - recalls the memory surfaces and makes them the selected ones KEY - SHFT+R
      • Or With Memory - selects all the surfaces that are currently selected and all those in memory. DOESN'T APPEAR TO WORK FROM MENU KEY - SHFT+O
      • And With Memory - selects those surfaces which are currently selected and are in memory only KEY - SHFT+U
      • Xor With Memory - selects those surfaces which are selected OR are in memory, but deselects those which are in both KEY - SHFT+X
  • View:
    • Log - shows the log window, useful if for some unknown reason a map can't load, or some other unexplained phenomenon.
    • Actor Class Browser - shows the actor browser
    • Group Browser - shows the group browser
    • Master Browser - brings up the master browser, which contains all docked browsers.
    • !!!! THIS HAS DISAPPEARED - Texture Browser - show the texture browser
    • Mesh Browser - shows the mesh browser (boy is this getting repetative!)
    • Music Browser - music ...
    • Script Editor -
    • Sound Browser - sound browser...
    • Actor Properties - shows the properties of the currently selected actor or actors. KEY - F4
    • Surface Properties - shows the properties of the currently selected surface or surfaces. KEY - F5
    • Level Properties - KEY - F6
    • Advanced Options - This is where you get to change lots of advanced options, again
    • Viewports ->
      • Floating - change the viewports from fixed (default) to floating. Then you can move them around and resize to your hearts content.
      • Fixed - change the viewports to fixed. The borders disappear and you can no longer resize the views.
      • New Viewport - only enabled when in floating mode. creates a new viewport for your viewing pleasure.
      • Configure - allows you to choose a number of predefined viewport configurations
      • Close All - closes all viewports, use configure to get back to a standard view of the windows.
    • Background Image ->
      • Open - Open a bitmap file to display in the background, behind the viewports (with the default configuration you will not be able to see it!)
      • Clear - clear the bitmap, make the background the default white again.
      • Center - centers the bitmap
      • Tile - tiles the bitmap!
      • Stretch - stretches the bitmap (hey, this is too easy!)
  • Brush:
    • Brush Clip ->
      • Clip - clip the currently selected brush, for all the brush clip operations see Toolbox and Concepts sections for more details.
      • Split - split the current brush into two seperate brushes
      • Flip Normal - flips the normal
      • Delete All Clip Markers - deletes all clip markers.
    • Reset ->
      • Move to Origin - Moves the selected brush to the origin
      • Reset Pivot - Resets the pivot pooint (the point about which roations take place) to the center of the brush
      • Reset Rotation - Resets the rotation of the current selection, essential before making brush into a mover
      • Reset Scaling - Resets the scaling of the current selection, again essential beofre converting brush into a mvoer
      • Reset All - Resets all of the above
    • Add - See toolbox section KEY - CTRL+A
    • Subtract - KEY - CTRL+S
    • Intersect - See toolbox section KEY - CTRL+N SHORTCUT KEY CONFLICT
    • Deintersect - See toolbox section
    • Add Mover - See toolbox section
    • Add Special - See toolbox section
    • Open Brush - Opens brush prefab files (.u3d) KEY - CTRL+B
    • Save Brush As - saves the current brush as a brush file (.u3d)
    • Import - Import one of the following files as the current brush, dxf (Drawing eXchange Format, used by AutoCad and 3DStudio Max), asc (Also used by 3D Studio I think) and t3d (from File->Export).
    • Export - Export the current brush in Unreal Text format (.t3d)
  • Build:
    • Play Level - play the level in Unreal Tournament KEY - CTRL+P
    • Rebuild Geometry Only - redoes the geometry and the bsp calculations. Do this if your 3d view is out of sync. Also available on the menubar
    • Rebuild Lighting Only - redoes the lighting for the level. Also available on the menubar
    • Rebuild AI Paths - redoes the paths for the level. Also available on the menubar
    • Build Options - shows the build options. KEY - F8
  • Tools:
    • 2D Shape Editor - brings up the 2D shape editor.
    • Scale Lights - allows you to scale the brightness of all lights in the level by a given percentage or absolute value.
    • Replace Textures - Allows you to replace one texture with another texture through-out the map. Slight bug at the moment in that you can only bring it up once, and after that it requires a restart to appear.
    • System Plugins - Not yet implemented
    • Level Plugins - Not yet implemented
    • Viewport Plugins - Not yet implemented
  • Help:
    • Nope, this is an unsupported beta product remember! Why do you think you're reading this!
Icon Menubar
All of the buttons below are duplicated within the text menus. I have slit them up into the sections they appear above.
File
New Map, Open Map and Save Map.
Edit
Undo and Redo (N.B. Clipping requires two undos to undo it).
View
Show the browsers, Texture, Actor, SOund and Music in that order.
Bring up the Actor Property, and the Surface Property windows
Bring up various tools, 2D Editor (Tools), Mesh Browser and Script Editor in that order.
Build
Rebuild Geometry, Relight map, Rebuild Paths and show Build Options in that order.
The final icon is Play!


View Basics

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

How do I move around the view window
Lets split this into 2 sections, the 2D window and the 3D window
2D-Views
  • Left-Mouse
    With the left mouse button held down you can scroll around the map
  • Left+Right-Mouse
    With moth the left and the right mouse button held down you can zoom in and out
3D-Views
  • Left-Mouse
    The left mouse will allow you to rotate your view
  • Right-Mouse
    the right mouse allows you to move forwards and backwards and rotate left and right
  • Left+Right Mouse
    With both held down you can move up and down and from side to side.


The View Windows

The View Windows By: Blacksway www.unreality.org/blacksway blacksway@unreality.org
From Left to Right: Top - Shows the mode of the view. Right click for the menu options shown below Joystick - Turn Realtime Preview on or off. This means when you move blocks etc in other views this view will immediately show the changes. This will slow your PC down. KEY - P T - Top view mode, view the world from the top KEY - ALT+7 F - Front view mode, view the world from the front KEY - ALT+8 S - Side view mode, view the world from the side. All these modes are wireframe. KEY - ALT+9 The remaining symbols are the 3D modes explained later, and are as follows: Wireframe, Texture Usage, BSP Cuts, Textured, Dynamic Lighting, Zone/Portals. KEY - ALT+1 to ALT+6 (NOT IN ORDER)
Right Click Menu Options
The first menu option gives the modes for the view in exactly the same way that the icons along the top do. I will assume you can work out what the Top, Front and Side views are all about. The remaining modes are shown below:
Wireframe (or Perspective) KEY-ALT+1 | This view shows you the basic geometry of your map. The color coding goes something like this: blue - added geometry brown - subtracted geometry purple - movers green - portals pink - semi-solid red - triggers
Texture Usage KEY - ALT+3 | This shows all the different textures used within a level. The more textures, the more different colors.
BSP Cuts KEY - ALT+4 | This shows the way the BSP engine has slit the geometry into triangles, which is all the engine can really display. The more cuts the higher your poly count and node count are going to be. To try reducing BSP cuts, try making some geometry which the player does not touch into semi-solid, and also moving some structures apart slightly so that large faces do not need to be slit into smaller ones.
Textured KEY - ALT+6 | The standard texture view, and probably the one most people use for most of the map, especially as its quicker than the dynamic lighting one below.
Dynamic Lighting KEY - ALT+5 | This show all the textures and lighting as last calculated when the build was run. If you do not run the lights option in build then this view will look identical to the one above.
Zone/Portal KEY - ALT+2 | This view show the individual zones in a level. Good for checking to see if that water zone is completely closed off.
View Right-Click Menu
 | Show Active Brush: shows the builder brush KEY - B Show Moving Brushes: shows moving brushes, even through other geometry, can slow the view down Show Backdrop: Does this work! Show Coordinates: What does this do? Show Paths: Shows the paths between path nodes etc.
Actors Right-Click Menu
 | Full Actor View: Shows weapons etc as their meshes Icon View: Shows all actors as icons, including brushes Radii View: Like Full, but shows a red circle around relevant actors, triggers etc Hide Actors: Hides weapons, inventory etc, just leaving brushes
Window Right-Click Menu
 | 16-bit or 32-bit folks. Doesn't make that much difference on my PC.


Popups

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

The biggest change with the browsers is that they can all be docked into the master browser. The dock/undock icon is always the top left icon in each browser window.

As some of the images in this section are quite large I've split in up into sections. Below is a list of the different pop-up windows.

[ Browsers ]

  • Actor Browser
  • Group Browser
  • Texture Browser
  • Sound Browser
  • Music Browser
  • Mesh Viewer

[ Properties ]

  • Actor Properties
  • Surface Properties
  • Build Options

[ Others ]

  • Builder Options
  • Script Edit
  • Log Window


Actor Browser

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

The actor window shows the 'actor' objects available within Unreal Tournament. Their are far to many to go through here, check my web-site for reference materials on some of them.

The Icons are as follows:

Dock/Undock from the Master browser
Open a actor package
Save the current package
Create a new object, using the currently selected actor as its parent.
Edits the currently selected actor in the script editor
Edit the default properties of the current actor

Right-Clicking on a class will give you a number of options. These options are also available from the Class menu option.

  • Class->New
    Create a new class
  • Class->Edit Script...
    Loads the script into the script editor
  • Class->Default Properties
    Shows the actors default properties.

To show all classes (not just the actor ones) untick the box that says Actor classes only.

The bottom half of the window can be made to show loaded packages (as seen here)by choosing the menu option View->Show Packages

The other menu options are as follows:

  • File->Open Package
    opens a package that currently isn't loaded
  • File->Save Selected Package
    saves the package of the currently selected class. Do this after compiling any code changes
  • File->Export Changed Scripts
    will export and script changes to the relevant .uc file
  • File->Export All Scripts
    will export all the scripts to the .uc files, creating the directory structure as it goes.


Group Browser

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

This is a new feature added to the latest version of UnrealEd.

Basically and brush created belongs to a group called "None".

If you select a number of brushes and click the New Group icon then they are automatically added to this new group. However they still belong to the "None" group but can now be removed from it...

Icons

Dock/Undock browser
Create new group (you must have at least one brush selected to do this!)
Delete group (this does not delete the brushes)
Add selected brushes to the selected group
Delete the selected brushes from the selected group
Refresh the group list (e.g. any groups no longer containing any brushes will disappear)
select brushes in currently selected group
de-select brushes in currently selected group

Brushes will only be shown in the 2d views (has no effect on 3d views) if all the groups they belong to are ticked. e.g. If they belong to Group1 and Group2 and you untick Group1 then they will disappear.

Note: Group information is saved with the map.


Texture Browser

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

The Texture browser shows the currently loaded textures. When you load UnrealEd then no texture packages are loaded by default. Whenever you load a map, only those textures included in the map are loaded into the editor, not the whole packages.

Icons:

Dock/Undock from the Master browser
Open a texture package
Save the current package
Edit the default properties of the current actor
Move to the previous group
Move to the next group

To load a package choose File->Open and load one of the .utx files.

If you want to create your own package then simply create a new texture (File->New) and set its Package to the new package name you require. After you have done this you then need to save the package by choosing File->Save.

The drop down boxes contain a list of the loaded packages and then a list of the groups within the current package. Click on the All check box to show all textures from the current package. Note, some textures do not have a group and will not show up unless you tick the All button.

Other menu options

  • Zoom
    change the zoom of the textures, choose from 32, 64, 128 or 256
  • Files->Export
    export the currently selected texture to a pcx file
  • Files->Import
    import a pcx file (remember, only 256 colors!) into a package
    a special package is the MyLevel package, which as its name suggests is the current level, and will not be stored in a seperate texture package.
  • Edit->Properties
    brings up the properties of the texture. This allows you to set lots of different properties, and if you get into making your own animated or fire textures then this is where you can set them all.
  • Edit->Delete
     Delete the current texture from the package
  • Edit->Rename
     Rename the current texture
  • View->Docked
     Change the docked status of the texture browser
  • View->Set Size
     Sets the fixed size of all textures, i.e. they all appear the same shape (square) and the same size
  • View->Variable Size
     With this option the textures will appear at a certain percentage of their original size and shape.

The Filter box at the bottom does as it suggests, allows you to filter on the names of the textures in the current package.


Sound Browser

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

The sound browser, much like the texture browser show only those sounds in packages which have been loaded.

The top drop down box shows the loaded packages. The next shows the groups within the selected package. The list shows the sounds.

Play: Stop:

To play a sound select it and click on Play. If it is a looping sound then you can click on Stop to stop it.

Menu options:

  • File->Open
    opens a package
  • File->Save
    saves any changes to the current package
  • File->Export to WAV...
    saves the current sound as a wav audio file
  • File->Import from WAV...
    imports a wav into the editor
  • Edit->Delete
    deletes a sound from the package
  • Edit->Play
  • Edit->Stop
     Play or stop the sound
  • View->Docked
     Changes the docked status of the browser


Music Browser

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Probably the simplest browser window. Lists the loaded packages.

You can click Play to play the music and Stop to stop playing the music.

Menu options

  • File->Open
    open a music package
  • File->Save
    save the package as a new name
  • File->Export
  • exports the file to a .S3M file. Unfortunately it names it .WAV. Rename the file with a .S3M extension and winamp will then play it.
  • Files->Import
    I don't know that much about music, but I'm guessing you have to create a S3M file, rename it as .WAV and then import it into UnrealEd.
  • Edit->Play
  • Edit->Stop
     Guess what, play the music and stop the music!
  • View->Docked
     Changes the docking status of the browser


Mesh Viewer

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

This allows you to browse through the weapons, decorations and player models available to you. As far as I am aware you cannot export the meshs for the models.

The drop down lists the meshs available to you (shown is the Unreal 1 8-Ball rocket launcher).

Hold down the left-mouse button and move the mouse to zoom in and out.

Hold down the right-mouse button and move the mouse to rotate the mesh.

The list box shows the different animations for each mesh, along with the number of frames in each animation. Youcan choose an animation and then press Play to play the animation. Press Stop to stop the animation.


Properties

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Contents:

  • Actor Properties
  • Surface Properties
Actor Properties

The image to the left shows the actor properties window. This can be brought up by right clicking on an actor and selecting properties, by presseing the actor properties button on the menubar or pressing F4

The Level properties window is the same except shows the properties for the current level and is displayed by pressing F6
Surface Properties

Bring up the surfaces window by pressing F5 or right clicking on the surface and choosing properties.
NEW IN 425! The texture pack and name is now displayed at the top of the properties dialog box

The first tab shows various tick boxes for properties for the selected surface.

  • Invisible - The surface cannot be seen
  • Masked - The surface contains 'blank' bits, e.g. a grate or a fence effect
  • Translucent - The surface is see-through, e.g. water or glass
  • Force View Zone - don't know
  • Modulated - not sure
  • Fake Backdrop - select this is this surface is to show the sky
  • Two Sided - the texture will show on both sides of the surface (pointless for brushes, but useful for sheets
  • U-Pan - the texture moves horizantally
  • V-Pan - the texture moves vertically. To get a texture panning the other way, flip it.
  • High Shadow Detail - The detail of the shadow.
  • Low Shadow Detail - For large outdoor areas you can choose High and Low to give Super Low.
  • No Smooth -
  • Special Poly - something special no doubt
  • Small Wavy - a ripple like effect
  • Dirty Shadows -
  • Bright Corners - The surface is lit evenly
  • Special Lit - Only lit by lights with bSpecialLit set to true
  • No Bounds Reject - No idea
  • Unlit - the texture is unlit, and remains at its full brightness.
  • Portal - this surface is a portal. Usually you would use Add Special Brush to add a portal sheet or brush, and not set this manually
  • Mirror - makes it a mirror, this plus translucent makes it a reflective texture (e.g. marble)


Build Options

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

The main build options tab.

It is best (as advised by Epic) not to play with these settings unless you really must.

Changing the first slider (Balance Tree) has been known to correct BSP errors in maps sometimes

Clicking on Build will perform all the selected functions, including rebuilding paths.

Create New Path Network will try to place PathNodes in your map by itself. This can be good, and can be bad.


Other Windows

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Builder Options

This shows the builder option for each builder type (Cube, Cone etc).

The options are different depending on the builder type, but here we have the basics for the Cube builder.
Log Window

Shows the log of certain actions. If some action doesn't work for some reason then load this up and see if there are any errors.

You can also enter commands here if you know what they are.


Script Editor

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

This is the much improved script editor.

A list of loaded scripts is displayed on the left hand side and one the right a big blue area for the currently displayed script.

Menu Options:

  • File->Export Changed Script
    exports any changes you've made to the relevant .uc file
  • File->Export All Scipts
    exports all scripts to their relevant .uc files
  • File->Close
    closes the currently displayed script
  • Tools->Compile Changed
    changed code must becompiled into the .u file. This will compile only changed files
  • Tools->Compile All
    compiles all the scripts

Icons:

Close the current script
Compile all changed scripts (remember to save the pacakges after doing this!)
Compile all scripts
Open the actor browser window (but if its already open in the background then it does nothing)
Find text in current script
Find previous case of above
Find next case of above


FAQ and Bugs
Q. How do I view the Textures, the menu item seems to have disappeared | A. You'll just have to use the icon (looks like a painting) as the menu item seems to have disappeared.
Q. There seem to be some shortcut key conflicts | A. Correct, they are as follows:- SHFT+S - Select All Surfaces (Works) and Select Adjacent Slants (Doesn't) CTRL+N - New... (Doesn't Work) and Intersect (Doesn't Work)
Q. Some keys crash UnrealEd or don't work | A. SHFT+G (Select syrface matching groups) crashes UnrealEd Or with Memory - Doesn't work from Menu, use SHFT+O.
Q. Sometimes the tabs do not work correctly, e.g. I change tab and the old tab is still shown. | A. This is a known bug in the current version of UnrealEd 2.0. It has been made better, but still sometimes crops up, especially in the Surface Properties window.
(FIXED 430) Q. I have a problem where an extra vertex seems to be created when I move the builder brush | A. A bug, plain and simple. Reporting to Unreal pps now. To recreate, select 1 or more vertex of the builder brush, deselect the builder brush and then press Ctrl+Right Mouse to move the builder brush. I call this the 9th Vertex Wonder! THIS HAS BEEN FIXED BY REMOVING THE ABILITY TO MOVE WHOLE BRUSHES WHILE IN VERTEX EDITING MODE!
(FIXED 430) Q. I cannot use the mouse at all in the new 425 editor | A. Disable DirectInput inside UT (go to Preferences->Input->Use DirectInput). This should fix the problem.
(FIXED 430) Q. I cannot create a second triangle in the 2D editor | A. Confirmed bug - No fix
FIXED(425) Q. Equations do not work in the edit controls anymore. | A. This did not make it in time for the first version, but it will be in the next version.
FIXED(425) Q. I cannot access all of the brush builders because some of them are off the bottom of the screen. | A. This version of the editor has a minimum usable resolution of 1024x768. If you are running lower than that, you will have to increase your Windows resolution. Future versions will have a scrollable bar on the left side, so this will not be an issue anymore.
FIXED(425) Q. I cannot open any maps/texture packages/sound packages/etc! | A. This version of UnrealEd2 cannot handle pathnames that contain spaces (i.e. "program files"). This is a programming error that will be corrected in the next version. For now, install UT into a directory that does not have spaces in its name.
FIXED(425) Q. When I try to start the new editor, I get the following error message: "Cannot find ini:Engine.Engine.Editor Engine in configuration file". | A. This is due to the editor trying to use "unreal.ini" instead of "unrealtournament.ini". This will be corrected in the next version, but for now you can get around this by copying your "unrealtournament.ini" on top of your "unreal.ini" file.
FIXED(425) Q. I cannot call up the surface properties window, or see any actors in the actor class browser! | A. Something in the code is incompatible with older versions of the file "\windows\system\comctl32.dll". We are working on figuring out what the problem is, and the only workaround at the moment is to get a copy of that file from someone who does not have this problem and copy it on top of yours. Alternatively download latest version of comctl32.dll from my download page HERE
Thanks Warren Marshall for the answer to most of these questions in his mini-FAQ. This solved a lot of my probs!


BB Drac - Unreal Tournament UED2 guide FAQ

UED FAQ

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

With this faq I want to clear a few things that normally
don't show up in any tutorial.

Also check UED2 General info and tips for more information.

Q: Where is the screenshot stored?

 A: When you have made a screenshot in UT it will be stored in the
system folder "...\UnrealTournament\System".
It will have the name "ShotXXXX.bmp".

 Q: How do I find the editor and/or do I need to download it?

 A: The editor is installed with the game.
The file "unrealed.exe" is the editor and can be found in the system
folder "...\UnrealTournament\System".
Note that this is the original editor.
To get UED2 you need to get hold of and install UT patch 4.20 or higher.

 Q: I can see parts of my level through the wall(s), why?

 A: When you are able to see through a solid wall you have something
known as BSP holes (or HOM effect).
Check the tutorial on BSP for more info.

 Q: When I try to play my level I get "Unable to open package..."?

 A: This is because some of the file(s) needed to play the level is missing.
When creating a level and using custom sounds, textures or music you need
to make sure that each package/files is available when playing that level.
Music files (*.umx) go in the Music folder.
Sound files (*.uax) go in the Sounds folder.
Texture files (*.utx) go in the Textures folder.
Maps (*.unr) go in the Maps folder.
Skin and Script files (*.int, *.u) go in the System folder.

 Q: How do I change the speed of moving clouds/walls (U and V pan)?

 A: The U and V pan speed is Zone Info based properties.
Under "ZoneLight" you have two properties "TexUPanSpeed" and "TexVPanSpeed".
They adjust the speed of U and V pan inside the zone.

If you need to change the direction of the panning you can do this
by rotating the texture.

 Q: When I try to find some textures with the texture browser, I can't?

 A: The texture browser for UED2 do not allow you to show textures
that do not belong to a specific group.
To find them you need to check the button "All".

 Q: My mover do not block players and act weird?

 A: This is most likely a scaling problem and your mover have incorrect
collision size.
Delete the mover, reset the brush scaling and add a new mover.

 Q: I cannot see fog when I play UT?

 A: I do not know if this is standard, but for some people UT set by default
that volumetric light (fog) should not be rendered.

To fix this open the advanced properties, expand "Rendering" and make sure
that for each render device (Glide, Direct3D...) "VolumetricLight" is
True.

 Q: When I open UED2 all viewports are white (or gone), why?

 A: Sometimes, for some reason, UED2 do not initiate the viewports correct.
To fix this just go to "view" in the menu, select "Viewports" and either
select "configure..." and then just OK, or "New viewport".

Sometimes this happen because there is not enough available memory
present. Close the editor and a few programs. Open the editor again
and the problem should be gone.


Unreal Editing Basics FAQ

Courtesy of Planet Unreal

Planet Unreal

I received the Unreal game with my voodoo3 3000 AGP card but the cd didn't have the editor on it. Is there a site where I can download the editor?

Why the best Planet... Errr... Place... on the net. File Planet or the Unreal Tech Page. The file is called UnrealEd Experimental Fix #4.

My Editor starts with an "Unexpected Error" and will not do anything else. Why doesn't it load?

The editor that ships with the game itself is fine, but it won't run on many system configurations. it's easily fixed though. There are two files that should do the job for you. Firstly, Visual Basic Runtime files (Ver 5.0 or later should do the trick) and secondly a Rich Text Fix (patch of sorts) from Epic. With these two files, you should be able to run the editor without too much hassle.

My Editor takes forever to load. Can I speed it up?

In a word - No. Unreal Ed is a program that is very CPU intensive, and as with most things related to creation of complex three dimensional worlds, it's not something that will work as fast as you would like it to. Waiting can be a great time to think over aspects of work to be created.

My editor crashes every now and again. How do I stop it?

UnreaL Ed is a BETA release of software. it is not supported by Epic, and is not a fully featured piece of software. On certain systems, it will be unstable, but in general the safest thing to do is simply close all other active applications that are running in the background, and allow UnrealEd to use all the system resources. There are certain applications that will not allow the editor to work as well. While these are currently untested here on our machines, running certain "Anti Crash" programs will most likely cause UnrealEd to crash more often.

The safest way to not lose work is to simply save often, and under different filenames. This will also allow you to go back and look at how a level has progressed, and where those extra polygons suddenly came from.

Hitting CRTL-S will NOT save your work. It is a shortcut for subtracting a brush, so don't assume that you have saved your level this way.

E d i t i n g

The following questions have been asked by editors, with the best answers that we could supply to remedy the problems. (These are not in any particular order right now, but will be addressed into a more useful format soon.

I tried adding corpses to my level in a medical room. The problem is, they don't stay when I try the level out. Why?

Unreal uses models for the corpses. This means that they are just as realistic, and detailed as the player models in Unreal. This also means that they are treated in the same way as a corpse that a player model will leave behind when it's fragged. Unreal Zones default at allowing 3 corpses in the zone. You will find that the corpses are there to start with, but will be deleted from the level when additional ones are added from the battles. You can change the number of corpses that will sty in a level at a time by placing a ZoneInfo into the zone, and changing the number to another value. Don't set the value too high though, as it can really slow a lower end machine with even 5 or so corpses and a player model in one room.

Please could you explain to me why, In my created levels either jumping or falling a millimeter or so splats my player, even walking down a small step leads to the "Player has left a small crater" message please help sob etc!

When you create a level in UnrealEd, you have to compile it. This actually maps out where a player can, and can't walk, what will kill them, and many other things. This is done by pressing the F8 key (Or accessing via Rebuild the menu) and hitting the Rebuild Button. This will actually compile a playable level from what you have created in the editor.

The same thing should be done if the blaster fails to show the ammunition that it is firing, but makes the sound of working - even if you can jump and not die. The level has not been correctly rebuilt.

I Like to make a door that you'll have blast your way trough with heavy firepower, so that it crumbles/explodes after a couple of shots. Is this possible? (the door doesn't have to move/open)

This could be achieved in one of two ways. Firstly (Easier to do - less realistic) create a mover that is a simply block, and place it where you want the "door" to be. Make it triggerable via damage (Set in mover properties) and have it move out of the way of players shoot it (Somewhere off from the level is best). Have it move instantly, and without any sort of noise or effects. Next, place a glass wall in front of the mover, and have it explode when damaged (Like glass is normally done in Unreal) simply setting the sounds to be an explosion rather then smashing glass, and texture it to look like your door should look. This will do the trick, although it will look pretty average.

If you want good looks and are prepared to work a lot longer, you should create a door as you want it, then split it into smaller pieces, that look like they have been blown apart (This is best done by intersecting) and create a mover from each of these brushes. Place the brushes together back as a door, and set each to "fly" backwards from the impact and land somewhere. Add a noise to each of these, and have them as separate brushes. Very Realistic, but hard and time consuming to do properly.

How can you manipulate textures in UnrealEd (that is move them at x & y coordinates, and possibly re-scale or resize them)? I've read in a few places that the 2d shape window can be used, but never any specifics...

No, it has nothing to do with the 2D Shape Editor. Simply high-light the textures (Press the left mouse button on it in the 3D view) that you want to move and then press the F5 key (Texture Properties). You will see a window appear. Pressing the "pan" section will allow you to very accurately move the texture. You can also use the built in interface buttons to move the textures over the surfaces of the brush. The buttons look like a small texture with arrows coming out of it and holding the CTRL key with the mouse button pressed.

I want to have a door with a window in it. How do I make it. Would I make like two different movers. One for the door and the other for the window. If that's the case how do you make a window a mover?

Simply make the door (Complete with window and whatever else you want it to have) and then intersect the whole shape into one brush. You will find that wt will keep all the characteristics of the door when it turns into a mover, and you only need one mover.

You just recently helped me with a fake backdrop problem, and I really appreciate it. Now I am working on a multi-mover door. I have read all of the tutorials, but I haven't been able to solve a problem. I want a button in both rooms that the door connects. When you hit either button, I want the door to open, and I want it to stay open until you hit either button again. How do I make it so the door does this? I couldn't figure out how to work the trigger this way. Thanks again!

In the mover properties, simply make the mover a "Trigger Toggle" type mover. This means that it will move to a new position each time a trigger is pressed. It doesn't have to be the same trigger (Hey, you could set up trigger that only work once, and have the player HAVE to seal the door shut in a hurry, or run into a rather nasty monster....). Sorry, got carried away there. Anyways, making the mover "Trigger Toggle" will do the trick for you.

Any brush I make is in a fixed location and stays there. Am I missing a command or is there an error somewhere?

To move a brush once it's in the level, select the brush itself (easiest way is to click on it in the 2D view) then hold CTRL and the left mouse button and drag the mouse across (or up or down or whatever) in the 2D view. If you use the right mouse button, you will find that the brush will rotate.

Often i have troubles aligning odd textures that aren't static such as the ones found in the *fx texture packages. any tips?

Yes, the easiest way to align things like that is to use a texture that aligns easily. Perhaps a brick, or something like that, then when things are aligned like you want them, simply change to another texture - and it will still be aligned. The only problem that you may find with this method is that some textures are different sizes, but generally speaking, it's the easiest way to do it.

Do you know how I can get the lava texture to be bright? I've got lava in a dark room with just a few dim red lights. The lights work well for the glow coming off the lava, but the lava texture itself is barely visible. Is there a way I can get a surface to ignore the world light?

Yup, this works for all textures that you want lit up nicely, and looking bright, like they are emitting light. Simply set them (in Texture Properties) to be "Unlit". This may sound to give the opposite effect, but what it does is make the texture not affected by any sort of lights in the level. It will simply stay at the brightness that the texture has been created in. This means that lights (Generally made to be bright in the original texture file) look much brighter than the area around them, and the same goes for lava.

I built a four sided room and have a hallway connected on each side. What I am trying to do is while I am standing in room I want to have each hallway entrance covered by a fake wall. I have the north and west sides covered but when I try to cover the south or east sides it puts the texture on the wrong side. How do I get the texture on the correct side?

You can do one of two things. If you want the wall visible only from the outside, then simply rotate the brush to face the opposite of which way it is facing now, or if you want the wall to be visible from both sides, go to "Add Special brush" and choose 2-sided and it will appear like a water surface, so that you can see it from both sides, but still go through it.

I was wondering how you would go about duplicating room? I want to make a long tunnel, I've made a 1024 long section and I want to duplicate the room and stick a bunch of these sections together... how do I do it?

Highlight the brush (In a 2D view) and hit CTRL W. Wvaalla. New brush just like the other one. Just place that where you want it to go, and rebuild, and it will be there.


BB Drac - Unreal Tournament UED2 guide General info and tips

General Info and Tips

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Also check the FAQ for more information.

 Texture browser:
To show ALL textures you need to check the checkbox for all.
The reason is that the texture browser will never
show any texture that does not belong to any specific group.

 Playing UT:
UED2 stores your UT settings and restores them when you
quit UED2 again.

 Realtime Editing:
If you activate realtime update in UED2 all animated textures and lights
will animate, invisible walls and zone-portals will disappear and you will hear sounds.
(Things will maybe not go at normal game-speed though).

 Other music/sfx and textures:
Deus Ex use the exact same game engine as UT and have the same
system of using music, sounds and textures.
All filetypes are stored on the disk as .uax, .umx and .utx.

 Player size and movement:
A player occupy 84x36 units (cylinder).
(Even if the player is crouching).
A player is barely able to exit from water if the distance from water
to the edge is 32 units.
A player is able to jump 72 units up and, barely, 344 units across.
A player is able to step/walk if the height is max 28 units.
A player is able to hammerjump a far way up, close to 464 units, keep
that in mind when creating levels like AS and CTF.

 Custom sounds, textures and music:
If you use custom objects (sound, music and so on) in your level make sure
it is made available for others by either importing it to "MyLevel" package or
include the correct package with the map.

You should also make sure that the filename of the package is the same as the level.
It will make control of what package belong to what level easier and when you create
other levels with the same or new included objects the package may change.

Never include imported objects in any of the original packages.
No-one is willing to overwrite their original packages to include your modified ones.


UnrealEd 2

UnrealEd 2.0 Tips

By: Dean "Goldabar" Tate

goldabar@planetunreal.com

General Tips

Here I'm basically going to ramble (in point form) some rules and general stuff that I follow when I'm mapping. As I learn more and more about mapping I'll be adding stuff to here (maybe even some tips on Real Life maps) so make sure to check back here every now and then! These are just general tips so I'm not going to organize them in any particular fashion, so grab some popcorn and get ready for a long read!

-Lately I've found that the best way to get inspiration for a particular map theme that I'd like to do is to surround myself in anything that has to do with the chosen theme. For example, the map I'm working on at the moment is gothic themed, so I've been looking at websites such us this to gather inspiration and ideas. Once I have a collection of pictures and art from websites such as this, I start sketching ideas that are a "mixture" of elements I've collected. Once this is done, I look at the plan of my map to decide where these different elements can be placed.

-Design your maps around different gameplay elements, such as weapon placement, and strategical elements such as cover from fire (from things like pillars and winding corridors, etc. These be fun when being chased by rockets, heh). One of the largest mistakes I made with DM-Spiridian was that it was in no way designed for gameplay, it was designed to see what sort of pretty pictures I could make in Ued (Heh, I should've said this in the ReadMe file, I've gotten a lot of backlash over this. Oh well). Never make this mistake unless you too just want to have some fun making architecture. Below you can see the plan for the map I'm currently working on, the layout for it has pretty much been dictated by what items will go where (take a close look, I've labelled the item placement):

-I guess there are certain rules that most people follow when placing certain items into a map. For example, I always place shield belts in high risk areas that are difficult for the player to reach, like the water trap in Spiridian. Its also good to make sure that there's only one entry and exit point to an area contain the shieldbelt. If you take a close look at the above plan, you'll see that once a player has grabbed the shieldbelt they have no choice but to jump from a large platform, that could lead to danger below (you know, large bears and crocodiles, that sort of stuff. Lions and Tigers and Bears. Oh my). This helps towards making the map just a tad more strategical. Also, place weapons such as the flak cannon in cramped spaces, where they're useful.

-I've noticed in a lot of maps that sometimes items such as the shieldbelt and basic armour are placed in complete dead ends. Personally, I don't do this, although I'm sure the more hardcore players out there may love it. To me doing this can just completely disrupt the flow of the map. I've played maps like this and heard the call from other players saying "Why the hell are these dead ends here? They're annoying" and I'd have to agree.....why are they there? It's just as easy to make a difficult and high risk area for these items to be accessed, without disrupting the map flow.

-Make your architecture as "three dimensional" as possible, without breaking the poly limit (you, in the back, screaming out "Hey what about Spiridian?"......shut the hell up) What this means is, don't use too many brushes "flatly". Let them jump out at the player so that they can see that "yes indeed that's a brush, not a texture". For example, try out different styles such as what I did here:

This was one of the few areas of Spiridian that stuck to the 250 poly limit (in fact from most views it didn't go over 150-200) but still managed to look great because of some interesting design elements. Here I have a ton of simple cube brushes stretched out all over the place, criss-crossing over each other to give a true sense of solidity to the area. Here you don't just feel like you're in a very nicely painted cube, there's a lot more going on. Try this as much as possible, as it leads on to my next point.

-Lighting. I suck at it, but I'm learning. As I said in the above point, its great to make interesting architecture this way. But what I have yet to learn (well, what I'm learning and doing at the moment) is to make good use of this type of architecture for some interesting and varied shadowing effects. Once architecture such as the above is in place, it's crucial that you make good use of it in your shadowing with clever light placement. Surround the architecture in brighter lights so that shadows will be created, and then if you wish to light the shadowed areas, put much more softer lights near them (brightness of say, 20-30, depending on the texture set). Don't let strongly coloured lights make your map "pretty". Sometimes its best to use even a saturation of 220 for some soft colouring effects. A saturation of 0? Avoid, avoid, avoid. Most of the time. Heh. Of course it depends on what sort of effect you're trying to achieve, but for the most part it's best not to go below 100-150 saturation, maybe even 180.

-Create contrast in your map with your lighting. Allow areas of the map to be completely dark, this will make the map much pleasing to the eye (unfortunately, as Akuma has told me tons of times, I didn't follow this correctly in Spiridian so please don't take it as an example). Make your map well lit so that players can easily make their way around, but be sure to keep small pockets of dark shadow around the place to add a little spice (erm......spice? I dunno what else to say. Oh well I'll edit this part later. Or maybe not. I'd say not)

-Try to use the 2d Editor as much as possible for the architecture in your map, and failing that, try not to use too many "flat" primitive brushes. Most of the time when I'm mapping I never use a simple cube, unless for example I'm just starting a new area in my map. Use vertex editing as much as possible, this is the only way you'll stop your map from being too blocky.

-Use semisolids on every single fricken' solid brush that you possible can (i.e. any solid brush that doesn't have a brush subtracted from it). This will help prevent BSP holes for the most part, and cut down on the node count of your map (I won't go all technical here on why it does that, so you're just going to have to trust me that it does. You do trust me, right?). Make sure the vertices of your brushes always stay on the grid. One thing I've noticed that lots of mappers tend to do is "combine" as many of their brushes as possible by intersecting/de-intersecting. I tend not to do this..well....ever, and so far I've had no problems. In fact I seem to get less BSP holes doing this, for example Spiridian is made up of over 2000 brushes and I only ever found 2 holes during the entire building of the map, and these were fixed in 2 seconds each by re-ordering some brush BSP orders. Easy.

-Use meshes to add detail to your map, but keep in mind that you shouldn't use too many (more than 800 poly meshes in a scene is bad if I recall correctly, you can check this by typing "stat mesh" into the Ued2 command prompt).

-It's good to use a small layer of water just above the players feet in different sections of your map to add strategy. This can be used as an audio clue to other players in the level to give away the location of other players as they trounce through the water puddles. This is best used in areas that hold powerful items (the Rocket Launcher, the Shieldbelt, etc). The same can be done by placing strings of 1 or 2 Healthvials around the map. These won't give the player all that much advantage when they pick up the tasty little treat, but what it will do is give out a huge audio clue to other players in the map (Healthvials are loud when you pick them up. Very loud).

-Create geometry that's designed to use your chosen texture pack, not the other way around. When designing a brush I always firstly take a quick look at the textures I'm using and work out ways in which they could be applied to some nice architecture. Spiridian is a good example of this, as most of the brushes were created after I had a quick check of the texture browser.

-Try to be creative, don't just recycle old ideas into new maps. When this is done an entire style of mapping can become tired and old in the gaming community very quickly. Try coming up with innovative new gameplay and design ideas of your own without just taking a look at other maps and thinking "oh that looks good, I could use that". For me personally I can't see the fun at all in recycling old ideas, if I had done this from the start of my mapping days, I wouldn't be here anymore. I would have simply grown bored too quickly. Try to develop your own style (in map making and basically....everything else that you do I guess (I'm referring to art, stuff like that)). Be individual with your work, but please if you're going to be an "individual" just in general, don't be one of those A-holes that takes "individuality" as another word for um..."A-Hole". Heh. I hate those people).

-I stated in my earlier tutorial (below) that I make my maps piece by piece without doing a "rough map" first off (making the entire map layout with basic brushwork). Well, I've changed my ways. Now I do tend to make the whole map out of basic brushes before starting any serious work. What this allows me to do is have a quick run around the map to see if it'll play well before I've spent a hundred hours working on detail only to find that the layout is in fact terrible, no matter how good it looked on paper. So now I can't stress enough, plan your whole map out in Ued before doing any detailed work, trust me, this will save time and trouble in the long run.

Inspiration

HA! You thought I was going to talk about planning the map first didn't you? (Well I was going to then I went back and wrote this). One of the most important keys to building great looking maps (and anything artistic for that matter) is the gathering of inspiration. With inspiration you can find the will and the stamina to do whatever you want. Basically I gather my inspiration from everything around me, for example any art that I look at (classic and modern, also stuff like cartoons, cool movies, comic books, any sort of feedback from people who play my maps, and even just other games that I like to play). With inspiration you will be able to come up with fantastic ideas for what you'd like to build, whether it be an awesome Sci-Fi spaceship map (just 'cause you've been watching too much Star Trek or something.....although I never watch Trek, it's too boring) or an Egyptian temple, or, well, anything (A giant dog house? A giant bathroom? Hmmm I remember a map like that....)

Planning

I still find it hard to believe that there are people out there that don't plan their maps out before going into Ued and building stuff (although I do have some good friends that make great maps, but don't plan them out. I don't know how they do it to be honest). I like to spend a lot of time drawing up ideas and plans for my maps before I start making them (this takes a long time, but I start doing it just as I'm finishing the map I'm currently working on. For example, once I'm up to the finishing touches of a map, I start thinking up ideas for what I'm going to do next, jotting down sketches and ideas in my sketch book. Go check out the artwork section to see what I mean). Once this is done, I find that it's best to take a look through Ued to pick and choose which textures I'll be needing, and thinking up clever ways to use them on my geometry. I find this is good for getting a clear idea of how the finished product will look, and how it will work.

Next: Its all in the Details!

Next up I start slowly building up my map in Ued, adding detail as I go along and then, once an area has been textured, adding lighting. I know that most people like to build a rough outline of the map with simple brushes before they start adding any type of detail, but this is not how I do it (although I am starting to use this method more and more). I prefer to build the map area-by-area, this allows me to focus on the detail throughout development. This is useful because in this way my mind is always ticking over, thinking up ideas for cool details and brush work. If I went and stuck all the detail into my map near the end of the development, I think I'd get burned out pretty quickly and run out of cool ideas. The reason that I do my lighting right from the beginning of the development is that it keeps the map looking cool, and that spurs me on to keep working. I've tried building maps before without lighting them right until the end (I did this in SFTDM-Greyskies) and to be honest, once I was around half way through making the map I became extremely bored with it. I was sick of looking at dull, lifeless, unlit textures. One of the keys to building a good map is keeping yourself interested in it. Without interest and inspiration, you're.....well.....stuffed. Also, seeing as I do the lighting this way, I can continue to get opinions on it right throughout the development, from friends and of course my mapping buddies. Which brings me to my next point.

Opinions and Why They Matter

The best thing you can do while building your map (at least once it gets close to completion) is to share it around with friends and to get a clean new opinion on it. Once I have a map around half done I start sending it to my close friends, getting opinions on it and making changes to the map as I go along. The good thing about handing the map over to other people is that they can much more easily point out mistakes that you've made and improvements you should implement.

The Finishing Touches

Once this is all done, the the geometry, lighting and layout of your map is complete, it's time to finish it off. This usually involves getting the map pathed for bots (never underestimate the importance of this step, most people I know only play UT offline, including myself) and fixing any small errors you have made, for example BSP holes and badly lit areas. Now it's time to test the map. It's best to upload your "final" version of the map to an FTP (I call it "final" because this never ends up being the final version) and then send a message off to your to any mappers that you know to have a play around in the map for a bit of beta testing. Once all the kinks have been ironed out in your map, keep testing it because trust me, you will have missed something. Then it's time to add a screenshot to your map, and release it to the world!


Version 1 to Version 2

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

This tutorial should hopefully help people converting from UnrealEd 1 tutorials to UnrealEd 2 by giving a step by step icon/feature comparison.
1 - Add Brush |  | 22 - Snap Scale Brush |
2 - Subtract Brush |  | 23 - Select All Textures | Edit->Select All Surfaces
3 - Intersect |  | 24 - Select All Brushs/Actors | Edit->Select All Actors
4 - De-intersect |  | 25 - Select All Actors Inside Builder Brush | Not available - use the Drag Box to select more than one actor
5 - Add Special |  | 26 - Select None | Edit->Select None
6 - Add Mover |  | 27 - Invert Brush+Actor Selection |
7 - Cube Builder |  | 28 - Replace Brush with builder shape | Not Available
8 - Opps (sorry, missed 8 out..) |  | 29 - Replace Selected Actors with Actor from Class Menu | Not Available
9 - Sphere Builder |  | 30 - Undo | Menu Edit->Undo or MenuBar at top
10 - Cylinder Builder |  | 31 - Redo | Menu Edit->Redo or MenuBar at top
11 - Cone Builder |  | 32 - Texture Pan |
12 - Stairs Builder |  | 33 - Texture Rotate |
13 - Spiral Stairs Builder |  | 34 - Hide All but selected |
14 - Curved Stairs Builder |  | 35 - Show All |
15 - Sheet Builder |  | 36 - Hide S |
16 - Camera Mode |  | 37 - Hide Z-Axis | What was this ever meant to do?
17 - Zoom Mode | What the Hell did this do? | 38 - Vertex Snapping |
18 - Brush Rotate |  | 39 - Get Help | Never worked, probably never will
19 - Brush Skew | Use Vertex Manipulation instead | 40 - Camera Speed |
20 - Brush Scale |  | 41 - Toggle Grid Mode |
21 - Brush Stretch |  | 42 - Toggle Rotation Grid |
Notes

20, 21 and 22 are all the same function, but the snapping of the grid depends on whether you have the Grid Mode on or off (41). 20 - Brush scale actually scaled all 3 axis at once, which technically the new function doesn't do.

You should also note that a lot of stuff has been added that is not shown here.


Shortcut Keys

Editor Shortcut Keys

This is a list of short-cut keys that can be used in the editor to stop all the bother with mouse clicking. Some of them are listed in the menu, but others are not, so read through them, and I think you will find a few nice "easter eggs" in here that will make your editing life a lot easier.

Delete : Delete selected actors.

1, 2, 3 : Slow, medium, and fast movement speed.

F1 : Help.

F4 : Actor properties.

F5 : Surface properties.

F6 : Level properties.

F7 : Compile changed scripts.

F8 : Rebuilder.

B : Toggle brush visibility in the current viewport.

H : Toggle actor visibility in the current viewport.

P : Toggle player controls or realtime update of the viewport.

Shift-A : Select all actors.

Shift-B : Select all surfaces belonging to the selected surfaces' brushes.

Shift-C : Select adjacent coplanar polygons.

Shift-D : Duplicate selected actors.

Shift-F : Select adjacent floors.

Shift-G : Select surfaces belonging to the selected surfaces' groups.

Shift-I : Select surfaces with items matching the selected surfaces' items.

Shift-J : Select all adjacent surfaces(flood-fill).

Shift-L : Look ahead in the current viewport (no pitch or roll).

Shift-M : Memorize selected surfaces.

Shift-N : Select none.

Shift-O : Select surfaces from intersection of selected surfaces and memory.

Shift-P : Select all surfaces.

Shift-Q : Reverse the set of selected surfaces.

Shift-R : Recall memorized surface selection.

Shift-T : Select all surfaces which use the current texture.

Shift-U : Select union of selected surfaces and memorized surfaces.

Shift-W : Select adjacent wall surfaces (flood-fill).

Shift-X : Select exclusive or of selected surfaces and memorized surfaces.

Shift-Y : Select adjacent slanted surfaces.

Shift-Z : Select none.

Ctrl-A : Add brush to world.

Ctrl-B : Load brush.

Ctrl-C : Copy.

Ctrl-D : Deintersect brush with world.

Ctrl-E : Save as.

Ctrl-L : Save level.

Ctrl-O : Load level.

Ctrl-P : Play level.

Ctrl-N : Intersect brush with world.

Ctrl-R : Redo.

Ctrl-S : Subtract brush from world.

Ctrl-V : Paste.

Ctrl-W : Duplicate.

Ctrl-X : Cut.

Ctrl-Z : Undo.


From Paper to Pixels

By: Chris ‘Plutonic’ Blundell

http://www.planetunreal.com/plutonic/

plutonic@planetunreal.com

Making maps for the Unreal Engine.

by Chris 'Plutonic' Blundell

I always enjoy reading articles by other level designers about their process for creating maps, so, I thought to myself: "Why not take the time to describe my process of level design?"

Over the last year and a half, I have been involved as a contract level designer on three commercial projects and created a number of maps for the UT community, including CTF-Conquest, CTF-Revenge and DM-Frantic. During this time I have experimented with different processes for designing and creating maps for the unreal engine and have found the following to be most efficient (for me at least).

Before opening UnrealEd

I usually start sketching and writing in my ‘ideas book’, which I keep with me as much as possible. Sometimes I sketch features, such as rooms, a base for a CTF base or a decorative feature. Other times, I write descriptions of game play elements. In moments of absolute creative clarity, a whole map will appear in my mind and I slave feverishly to get it onto paper.

When I feel that I have a reasonably good idea of what I want the map to be like, I start sketching the layout. About six months ago, this process involved me drawing the map to scale on graph paper, but I no longer work this way. Instead, I now draw the essential layout of the map, including information about the relative heights of the levels in the map and any other important considerations.

I should note that, even though I start with a reasonably detailed idea of the layout for the map, it still evolves and changes as I create it with UnrealEd.

Bring on UnrealEd

1 Creating the 'flow geometry'.

I start a map by creating all the geometry that makes up the flow of the map. As each brush is created, generic textures for the floors, walls and ceilings are applied to the respective surfaces. This allows for easy realignment of textures after vertex editing and/or scaling. I try not to get side tracked into adding decorative details at this point (though I will sketch a really good idea on paper for implementation later).

During construction I add what I call ‘interim lighting’ - these are just lights with default settings placed in the map - and a player start point so that I can wander through the map in UT. This way I can check that playing space is appropriate, without having to wait for a long rebuild to finish.

2 Details, textures and lights

Only after I am happy with the flow do I add the elements that bring the map to life. I will usually create decorative geometry at the same time as I apply textures to the map. Ambient sounds, movers and meshes are also added at this point. The map is usually zoned before I start applying lights.

Once I am happy with the details and textures, I select all the ‘interim lights’ and delete them. I then go through the map and apply lighting with settings that are specific to the decorations, textures and intended theme. The sky box is usually added last. This phase normally involves a lot of play testing to check that the lighting levels are okay.

I will normally try to give myself a break from the map at this point in the process. Usually I try to take a day or so away from the map, though sometimes I really have to force myself to step away for that long. This allows me to come back to the map and review my work more critically

3 Weapons and game play elements

Where possible I try to place weapons, power ups and associated elements to promote strategy in game play. It helps to have the geometry finalised before doing this. Game play elements, such as CTF flags and defence points, are also added at this time.

4 Path noding

As you are no doubt aware, bot paths are dependent on geometry and game play elements. So I tend to add them only after I have placed everything else. After I have looked at and then tweaked the paths in UnrealEd, I then load the map from inside UT and watch the bots play the map. This often results in me going backwards and forward between UnrealEd and UT, trying to get the bots to play the map effectively.

5 Tidying up

Music, the screen shot and level information are normally added last.

6 Beta testing

I find the opinions of others invaluable because they can look at the map through fresh eyes and quite often see things I have not noticed. I try to incorporate as much of their advice for changes as possible because, more often than not, they suggest things that everyone else will want to see in the map.

7 Releasing the map

There comes a time when a shipwright must stop working and watch his/her creation sail into the great unknown. The same is true of a map designer’s work.

End note

This article is only an expression of how I go about making maps. Given the fact that most people have more or less taught themselves to use UnrealEd, I am sure that there is a multitude of processes for designing and making maps for UT. I would not presume to think that my technique is any better or worse than other designers use. What I can tell you is that this technique helps to avoid the problems and distractions that plagued me when I first started making maps for Unreal a couple of years ago. In particular, it forces me to consider the flow of the whole map first, before being caught up in the process of decorating it. Thereby maximising the potential for the map to work as a whole unit, rather than it becoming a interconnected collection of 'pretty geometry'.

Chris ‘Plutonic’ Blundell
[15-12-00]

http://www.planetunreal.com/plutonic/

plutonic@planetunreal.com

UT Maps by Plutonic (in chronological order from most recent):

CTF-Revenge, DM- and DOM-Frantic, CTF-EventHorizon, CTF-Conquest, DM-Fool’sBravado, and DM-AggressiveTendencies][

CTF-Revenge | DM- and DOM-Frantic
CTF-EventHorizon | CTF-Conquest
DM-Fool’sBravado | DM-AggressiveTendencies][


The Idea

By: Grimreaper
Artificial Insanity
grimreaper@planetunreal.com

You want to create your own map, but where to start?

First think of what sort of map you would like to make; AS, CTF, DM, DOM, or something totally different (ex. RA, SAS, etc.)

Is this your first map? Then it would be smart to start off with DM. But first think if you want to make a DM map for 1vs1/2vs2 gameplay or for much bigger teams like 3vs3 +.
It's obvious that you make a 1vs1 map a lot smaller then a 4vs4 map, because of the simple fact that you will never see each other if you play 1vs1 in a map that was designed for at least 8 man. You want to make a map where mainly FFA (Free For All) will be played? Then make a middle- to big environment where enough players can run around.

Are you more experienced in making maps, then try something different, ex. DOM.
DOM is mostly played in big teams of 4vs4 +. The secret of a good DOM map is that it's big and that the domination points are well spread over the entire surface of the map. The domination points are mostly at big open spots that are reachable from different sides.

CTF is also for the more experienced. At this gametype the size of the map is also very important, because CTF is played in very big teams, mostly of at least 5 man per team. Though it's not like a DOM map that it should be big in all directions, because CTF uses two "opposite" bases the map should especially be big in length (read walking distance). There should be different access ways to the base, so the defending of the flag comes down to where the flag stands. The map should have long walking distances because it should be possible for a team to intercept the enemy (who is on the run with their flag). At DM and TDM games the so called "campers" are not very beloved. At CTF however the teams are always split up in two, one part for the attack and the other for defense. So the defenders will always be hanging around their own base, preferably on a spot where they can see the enemy coming and ambush him without risking their own lives, so some of these spot's are very welcome in CTF maps.

With AS the real experienced work starts. AS maps exist out of two parts, the starting point for the attackers (covered, and with a lot of weapons/ammo/health/armor) and of course the base that should be defended by the other team. AS maps are also very big because it's also played in big teams. One team should attack the base, defended by the other team, and try to destroy important targets. So the map should contain a well defendable base that should be hard (not impossible) to take. In this base there should be some strategic targets.

An important aspect of all these gametypes is the so called 'Z-Axis gameplay', which means that the map should consist out of different levels and that those height differences have a strategic advantage over your enemy below, 2 hallways above each other are not interesting if there is no way to kill the person below very easily in a strategic way.

I haven't been speaking about RA, SAS, etc. maps yet. This is because it differs for each MOD how a map should look and play. The best way to find out is to look at screenshots and ask the MOD mappers for information, and if there is a public beta release already you should play that as well.

Now you know what sort of map you want to make it's important to think of how you want the map to look. There are 3 different main themes (each own variation is possible):
Ancient, think of castles, churches, Egypt, Greece etc.
Urban, mainly in the present time with realistic environments.
Space, futuristic maps on other planets, spaceships and post-apocalyptic worlds.
Do a little brainstorm around the theme you chose and write down what you think of. Now you have a good idea of how it should look, in your head and on paper.
The next step is drawing, you should at least make a floor-plan of how the map should be divided. And if you're good in making sketches you should try to make some 3D drawings of certain parts of your map. Have you made drawings of your map and provided it with measurements? Then you shout now be ready to start working in the editor. Something very important, searching textures that fit with the theme you chose (you don't put spaceship textures in a church :). If you have also figured this out you can make the map.

If you followed all these steps, it's still not sure if your map will be a success. A few very important aspects of a map are gameplay and looks. The looks are mainly done by good measurements, good lightning, good texture placement and eye for detail. Do watch out that you don't go to far with those details, the more detail the harder your computer will have to work, and that degrades the gameplay. Gameplay also consists of playability of a map, weapons and powerups placement, and bot support. You have paid attention to all these point then there is no other possibility that you have created a great map.

By: Grimreaper
Artificial Insanity


Basic Room Overview

    By: Isolation

    You might think I am crazy but UnrealED has to be one of the easiest level editing tools I have ever used in my life. It's fast, advanced, and has a killer interface. So let us begin with a brief introduction of UnrealED. UnrealED is not the same as a Quake or Doom editor, instead UnrealED is based on "Constructive Solid Geometry." CSG is basically a huge block, and you carve out little by little out rooms. But that's not all you can do. You can also add brushes just like you would for a Quake editor. If you couldn't we would have levels with just boxes and that would be boring as hell. ;) Now that the boring stuff is out of the way let me explain how UnrealED works. Basically you have your red marker that you can shape in any way you want (rectangle, squares, spheres, cylinders, etc). With this you can subtract and add onto your map. So you cant add a brush, make it how you want it and then move on, no. Instead after you have to shape your marker, then make the room.

    You first room
    So let us begin click on the Cube. On the toolbar of the UnrealED interface. It is the 7th button down on the last row. A red box (Figure1) will appear. I call it the red marker (I don't know if there is an official name for this :b) Now the red marker is your friend learn to love it because your whole map will be constructed by it.

    Now right click on the same Cube button on the toolbar and you will see a small menu. Click on Cube Properties ala Figure 2. Now you will see the Cube properties. Here you can choose the Height of the cube, the Width and the Breadth. Just play around with these settings and you will see how the cube changes sides (click on build for the cube to change size).

    Now make a cube 300x400x500 (heightX,widthY,breadthZ) and click on close. Before we go on I want to talk about textures. Thanks to the creative and talented artist team of Epic and Digital Extremes we have packs of kick-ass textures. So in the texture toolbar (on the right side of the screen) click on load (bottom right of the screen). Then you will see a menu of .utx files, choose any texture pack you wish to use. Be warned some of them are just for special FX and liquids. I choose SkyCity because personally it's my favorite along with NaliCastle. Now click on open. It might take a while to load. As soon as it's done go to the drop down list, on the top-right corner of the screen where it says "All" click SkyCity or whatever texture set you choose. Then on the drop down list below where it says "All" click on it and choose Walls. Thanks to UnrealED all the textures are in groups of Walls, Deco, Base, Ceilings, and more. Pick a texture you wish to use. Now back to creating your first room you should have your red marker ready from before. Click on the second button down on the last row of the toolbar. If all goes well you will see a room with a texture. There you have just took a piece of the huge cube that you can edit from.

    Moving the Grid and Objects

    Maybe this section should go before I don't know but this is how you move your grid in UnrealED.

    Right Click + Moving Mouse = Move the Grid and objects on it
    Both Buttons Clicked + Moving Mouse = Zoom in and Out

    Now when you click on an object the object's color should change. The red marker should change to a darker red then before. When you have an object selected these are the following ways to move it.

    Ctrl + Left Mouse button Clicked on Object + Moving Mouse = Move the Object
    Ctrl + Right Mouse button Clicked on Object + Moving Mouse = Rotate Object

    Moving the camera
    One of the greatest things of UnrealED is the first person window. It's so great because you can move around your map freely like if you were in the game. Here is the list of how you can move around. You have to hold down the mouse button when you want to move around.

    Left Click + Moving Mouse = Moving Forward, Left, Right, and Back
    Right Click + Moving Mouse = Free Look, Look up, down, all around
    Both Buttons Clicked + Moving Mouse = Strafe Left and Right and move UP and Down

    It is really easy once you get the hang of it so move around your new little room, go inside, outside do what you want. It's your world.

    Texture the room
    Ok so the room looks big and boring with the same texture. So on the bottom drop down list where the texture menu is click on floor. After you do this you will see a bunch of floors textures. Click on the floor of your room and then click on the texture you want to use for the room. After that, do the same for the ceiling, but instead look in the ceiling group of the textures. Now you can use any texture you feel like using. A wall doesn't have to be a wall texture it's just a way that DE and Epic made UnrealED much easier to find the textures.

    Add the PlayerStart
    Ready to play your newly created map? Then on the texture menu you should see a drop down list where it says Textures. Click on the list and instead of pick Classes. This section has every entity you can put in Unreal (unless you create your own with Unreal Script, but that's a whole other tutorial). Now click on the dot besides NavigationPoint. The menu should get bigger. Then click on PlayerStart. You are now ready to throw in your first entity. Right click on the grid in the level and you see a menu. On the menu you see click Add PlayerStart on the top. Now you should see a joystick inside your map. That is where the player will begin the level. Make sure the player is INSIDE the room and close to the middle. I don't think the player would like being stuck to a floor.

    If you wish to play your newly created level right click on grid again and click on the button Rebuilder or just hit F8. You will see a Geometry tab before you do anything make sure Auto BSP is unchecked. Click on Rebuild Geometry, then go to the BSP tab and make sure again that Auto Light is unchecked. Now click on Rebuild BSP and you are set to go. Just hit Ctrl-P or File -> Play Level and you are on your way. If you want to learn how to put in lights keep on reading.

    Lighting your map
    One of the coolest features of the Unreal engine itself. Lighting but before you go on and start putting in nice lights that stick out lets put in a simple light. To do this right click on the grid and click on Add Light (or Ctrl-L). You should see a torch. Move the torch to the center of the map and then right click on the grid, go to Rebuilder (or just hit F8). Go to the Geometry tab and click on Rebuild Geometry, then go to the BSP tab and hit Rebuild BSP. Last but not least go on the light tab and click on Rebuild Light (or something close to that). When you are finished your room should be lighted in the first person view and you are ready to go on your first map!

    Advanced Lighting
    Nothing big here but if you want to change your light settings do this. Click on the torch and then right click it and you will see a menu. Click on Light Properties on the menu and then you will see a blue menu pop up. Go to Lighting and there you can choose the color, brightness, volume, what type of light and lighting effects. There will be a later tutorial for more advanced lighting so look out for that.

    Geometry, BSP, and Lighting
    Almost everyday in #UnrealED I mention in the topic that Rebuilding is the key to making the level. You have to keep rebuilding after making drastic changes so that it shows up in the window. It doesn't take long at all, same with BSP. Lighting also doesn't take much time to do so you would like to check out how your level looks with the lights every once and a while. So after building your map keep on rebuilding, it will help you.


Making Rooms and Connecting Them

MAKING BASIC ROOMS AND CONNECTING THEM…

By : Matt Murphy

utcity@planetunreal.com

UT City

FOREWORD:

I am suspecting that you know how to start up UnrealED. Download tutorial map: Here

DIRECTIONS:

First go ahead and start up UnrealED. Now you should see something like this: (Note:The blue lines aren’t there obvioulsy, I’m just pointing out some of the button names for you.)

Well the first thing you’ll probably notice is that there’s a lot of stuff to know. Don’t worry about memorizing them all now because the more you use it the more familiar you’ll get with it. Also notice the 3D view, if you click on it and hold it you can move your view around. Hold the left button to move forwards and backwards, hold your right mouse button the look all around, and hold both and move your mouse to go up and down. Ok, now, in the bottom right hand corner where it says “Load”, click on that. Now select the texture packet called “Crypt2.utx”. Now a set of images should appear in the menu viewbar (refer to above image). Select on the texture entitled “C_FLR19”. This will be our texture for the walls. Now right-click on the create cube button and select cube properties. When in the “Build a Cube” dialog box click on solid, then put the height as 384, the width as 384, and the breath as 384. Then click “Build”. Now click on the add button. Now take a look at your 3D view, it should like something like this:

Now go to your XY view or top view above your 3D view and hold Ctrl and move the red box (known as your brush<<remember THAT) RIGHT ABOUT 128 UNITS SO IT LOOKS SIMILAR TO THIS:

Now again press the add button and you should end up with two identical squares. (Note: You use the add button when making a box outside of another, and you use the subtract button when making a box inside of another.) Now right-click on the cube properties button again and make it solid, height=256, width=256, and breadth=128, then press build and close the build a cube dialog. Now place it in between the squares and along the bottom like so:

Since the brush is in between the cubes but still not inside the cubes we are going to press the add button again. So go ahead and do that. Also this will only connect the cubes if you’ve made them exactly 128 units apart. Look below and if your map looks like that then now you’ve got a connected hallway! (Remember to move your camera around to see the inside of your level.)

Great work so far. Now we’ve got to add some lights. Look at your 3D view and rotate your camera position so that your looking at one of the box’s ceilings. Now right-click on the ceiling and select “Add Light here”. You should notice a small torch on the ceiling. Good. Now rotate your camera view and look at the other box’s ceiling and do it again. Now you’ve got lights on your level. Now is the only technical part. In the Mode Toggler click on the pull-down menu bar and select Classes. You should notice a small minus sign next to the word (*NavigationPoint). Click on that. When it turns into a plus sign you should notice that there are a lot more options to choose from. Select the option that says “*Playerstart”. Now go back to looking at your 3D view and take a look at the floor in one of the cubes. Right-click on the floor and select “Add Playerstart here”. You’ll notice a small joystick appear on the floor. Good, now go over to the other cube’s floor and do it there. Now there’s only one thing left to do and that’s to rebuild geometry. Press the F8 button and under the Geometry tab select the Rebuild Geometry button. Your level should look something like this now:

If it does then go to the file menu and save it as DM-test and then save it and then go to the file menu again and select Play Level (Make sure your Unreal or UT cd is in the CD-ROM drive.) If it does not look like the above then go back and see where you’ve made a mistake.

HOW TO EDIT TEXTURES…

Played your level and notices it was all a single texture on every wall and want to change it a bit. This is how. First in the 3D view select on any floor/ceiling/or wall and then find the texture you want while it is selected and then select that texture that you want. It will instantly change textures. Pretty easy huh?

CONCLUSION:

You now know how to make a basic level, add playerstarts, add lights, and change textures. Try experimenting with new shapes and buttons. Also open some other textures packs and check those out. This is only the first step towards level making but it’s a very good foundation to start on.

OTHER:

Questions/Comments email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


UnrealEdMax - Maximum Unreal Editor 2 Tutorial Content - The Definitive UnrealEd v2.0 Introduction

THE DEFINITIVE UNREALED v2.0 INTRODUCTION AND GUIDE

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

Welcome to UnrealEd 2.0 the best editor for any game available out there. Take it from me none of the other editors like WorldCraft and Q3Radiant stand a chance in a comparison test between them and UnrealEd. The ease of use, the fantastic interface and the superb 3d views are some of the features that make it the best editor out there.

WHO THIS TUTORIAL IS FOR:

I expect you to know ABSOLUTELY NOTHING about editing and the UnrealEd in particular. If you do know that will not be a plus or a minus. If you have used the previous version of UnrealEd and are looking to just brush up on your skills you may just want to read that particular topic on which you want more information.

FIRE IT UP:

Downloaded that massive patch?. Install the damn thing. Go to the ..\unrealtournament\system folder and locate and execute the unrealed.exe file that you will find there. This is the Unreal Tournament editor and will be referred to as UnrealEd from now on.

WHAT WE WILL BE DOING:

We will be creating a small death match map from start to finish. This map wont be something great, but since we will be discussing the whole process of map creation we will deal with nearly all the topics you will need to know about to start making maps of your own. I suggest that you set aside around 1 hour (if you have that much time that is :) and work this tutorial end to end. Remember to keep the editor and the tutorial open so that you can go read one part and then go and work it out in the ED this will help to reinforce your skills. Excited?, so you should be!, a magic realm of exciting possibilities wait out there so let the creative juices flow and enter with an open mind.

WARNING: At the time of the writing of this article I am using the v436 patch, certain things could be added or changed in the next few releases. This tutorial should still be relevant then but a few extra buttons may be in other places and a few behind the view changes may take place I cant say for sure.

YOUR FIRST FIVE MINUTES

Fire up the editor and have a look around. This is how it should look like:

Whenever you create anything it will appear on the various views. What is the core concept of the UnrealEd?. The whole world is already "filled up" i.e. there is already a full solid area, any room that you want to make will have to be chiseled out of this solid cube (know as Constructive Solid Geometry). Once you have made your basic room you can add in all the stuff that you want. This is opposed to the Q3Radiant concept where you have to first make solid cube yourself and then you will have to chisel it out. Now take a look around the editor the tool bars default location is on the left these are the various stuff that you can use in the ed. The last group of icons - those pictures of the cube cylinder, etc are the base items that you can work with in your level. The 3d view of UnrealEd is superb you must make it your best friend. To move around in the 3d view hold down the left mouse button to move forward and backwards and turn left and right; hold down the right mouse button to look around; and hold down both the buttons to move up and down and strafe left and right move around in the 3d view now and get used to the feeling of this it is not unlike normal FPS game movement. You can hold down the left mouse button to move around in the 2d views and to zoom in and out hold down both the left and right mouse button.

THE FIRST ROOM EVER

Lets build your first room to get a sense of accomplishment. First and foremost load a texture package. The unreal texture packages are in the utx format, you load a texture package by hitting this button [image]. There are some default textures loaded lets not bother with them. This is one of the fun part of the level building deciding the general theme of the level and all that. Lets load a package called UTech1.Hit the texture browser button shown here (its located near the top of the screen) and when it opens from the from the file menu choose open. It should immediately jump to the open texture package dialog box and show the textures on your system (if not browse to the ..\unreal tournament\ textures file and open it). Choose the UTech1.utx package and hit and hit open (since I have a high end TNT2Ultra ...... well at least it used to be......... system and 192 Mb ram I usually end up loading every single texture package on my system). The browser now shows the loaded texture package, like this:

Use the subclasses menu to view the type of textures that you want to use - for example you may want to see only the wall or floor textures that the package contains then you just need to choose it from the drop down menu. Once you are more familiar with the texture packages you can start to use the filter box, for example you can check the all radio box to show every texture and find all textures whose names start with c. I have also set the zoom form under the zoom menu to 256 so that the textures are nice and big and you can see what you are working with. Now from the subclass menu (incidentally this is a name that I made up it could be called something else) choose wall and pick a texture that you like by selecting it. Now let us create the first room from the primitive cube that is available to us. The picture below shows the primitives that are available to us. For now just consider the cube I will show you how to use the rest at another part of this tutorial. Right click the cube to access its properties:

For now enter the values of 512 in the height, breadth and width fields don't bother with the rest for now. The red brush is called the builder brush - using this brush you will be able to build various shapes. If you were to hit any of the previous primitive shapes you will see that they appear in the views. What is the purpose of the builder brush? - it defines the shape of the brush before you make any "final" moves so that it becomes part of the world. With just the builder brush sitting there nothing has changed in the level, lets rectify this now. Hit file new and when asked to save changes choose no. Ok now that the new map has loaded lets create that room. Remember what I said previously, since the world is already filled up we have to punch out the room from this piece that has already been given to us. Hit the cube button and the builder brush will appear in the various views. Now we are going to subtract this shape from the world so that the room is created. Just hit the subtract button from the tool bar (I will be explaining how to use the rest one by one so don't get scared off) or ctrl+s:

The room should appear like this in the 3dview now (note I am running in D3D mode to change from the default software rendering mode to D3D in the 3d view right click on the toolbar type and check D3D). Ok since I was not satisfied with the textures for the room it was time to change them. There are two ways of doing this - first select the texture that you want to use for the walls from the texture browser, next hold down ctrl and click on the four surfaces of the wall in the 3d view and with the texture browser still open double click that texture you want to use to apply it; or choose the texture that you want to use minimize the browser, go to the 3d view and while holding down ctrl select the four surfaces of the wall and while they are still selected right click and in the menu that appears choose apply texture : floor 3b for example. Now the room should look like this:

How was it done?. I just choose floor from the subclass menu in the texture browser and using the technique described above I applied it to the bottom of the box that was going to form the room, in the same way I choose wall and applied it and ceiling and applied it. The name of the textures that I used were: floor - floor 3b, wall - ClifCon7, Ceiling - nmceiling2lt3. Looks nice hah!. Well we now have a room. Lets add some thing into the room to make it look better.
HEADS UP: You should only add in things using the add button to that portions of your level where you have already subtracted something. For example if add in something outside the room that we created you would be effectively placing some solid where a solid already exists. This will create problems for you later.
NOTE: When you create the next primitive remember that you can use normal operators in the primitives properties. For example in the cube above if you wanted to create a cube with a height less than 512, you could have entered "=512-128" (without the quotes) in the height field and hit build. UnrealEd will automatically calculate this value for you. As you can see this will prove to be mighty handy as you don't need to keep loading the calculator.

Lets add in some pipes to make the room look more complex. The pipe is nothing more than a cylinder on its side. I set the properties to (by right clicking on the cylinder in the tool bar) :- Height=512,OuterRadius=64 and Number of sides =12 ,leave the rest alone for now. Now the cylinder was pointing straight up. We want it to run along the walls so we will rotate it. First just in case you rotated the brush before by mistake select the brush in any of the 3d views by left clicking it. Once it is selected right click and scroll down the menu till you come to reset and choose reset rotation. Now select the brush again and in the side view while holding down the right mouse button rotate it so that it is on the side now move the brush up and down if you have to, get it in the center of the room. Adjust it in all the 2d views so that you place it correctly and hit the add button. Move this down (you may want to do this in the 3d view by selecting the builder brush holding down both the mouse keys and ctrl and moving the mouse in the desired direction). now do it so that you have 3 pipes in the room or you could leave it a one so long as you have understood the concept of adding in solids and moving the red builder brush. And here's a final look at the end product of your very first room:

Is this baby ready to run yet? Nope still some way to go.
NOTE:- You may have difficulty lining up the brush if your gird is too big. You can change this by right clicking in any of the 3d views and under the gird menu selecting the one that you want. You can also choose the gird size from the pull down menu next to the command bar at the bottom of the Ed.

LIGHTING - NORMAL AND COLORED - PART 1

AH! It feels so nice to introduce this concept in the very first tutorial that you are going through. In the old UnrealEd there was a need for a separate tutorial on how to use colored lights in a level because it was so badly implemented. In UnrealEd2 its so easy I decided this funky concept should be discussed at the start of your editing experience. You should be aware of the fact that lighting is what makes a level stand out. Sometime back I read an article on the importance given by game companies who want to hire designers when judging their work - attention to detail and color and lighting came out at the top. The Unreal Engine allows you to take lighting effects to the max and beyond.

At this point if you were to play your level it would be totally dark. Adding in lights is as easy as holding down L and clicking anywhere in the 3d view to place a light at that exact spot. Alternatively you can right click on any surface and hit add light there from the menu. Add one light to the ceiling, it looks like a torch, select it and drag it to the exact middle of the room. Just add in one more near the ceiling. We'll come back to this in part 2 after we discuss some other stuff.

REBUILDING AND PLAYING THE LEVEL

HEADS UP: What is an actor?. An actor is any item that can be added to your level from the Actor Class Browser. This could be any pre-made decoration, items, monsters and various stuff like triggers that let you control events. You can access any actors properties by right clicking on it and choosing that actors properties, or by double clicking the actor or by selecting the actor and hitting F4.You can hit this button [image] at the top of the editor to open the actor class browser at any time - shown on the left.

Lets go out and play this tutorial map. Before you play any map there are three things you have to do:

(a). INSERT PLAYERSTART: The player start is an actor that tells the game where to place the player when the game starts. If you play any level without a player start it will crash to your desktop with the message that your level needs one. So lets add one already!. First hit the actor class browser icon shown above (it is located next to the texture browser icon). The actor class browser will open up, now make sure actor classes only is checked (remember you can add in only actor classes to your level so there is no point in having the others shown). Now go down the list and locate something called navigation point - click the plus arrow to expand that menu. Locate the player start within that menu (don't double click it) just select the damn thing. The browser should look like the picture on the left. Lets just add it in the center of the room, minimize the browser and right click in the center of the room in the 3d view and hit add player start. Or while holding down A left click any where in the 3d view to place the player start there. The player start will appear as a small joystick in your level. Select and move it to the desired location (when you select any actor in the various views the selected actor will appear in green).

(b). REBUILDING THE LEVEL: This is also known as compiling the level. The various types of rebuilding options are: (from left to right) - [image] - rebuild geometry alone, rebuild lighting alone, rebuilding paths (to add bot support), build as per settings in build options, build options (rebuild everything and set individual settings). Rebuilding a level is a very important part of map building. When you make any drastic changes to a level you should immediately rebuild to see the kind of change that has been done to your level. For example when you added in lights previously you should immediately hit the bulb icon to rebuild lighting to see the effect. Lets rebuild the whole level. Hit the build options icon [ [image]] to bring up the rebuilder and check the following:

I will explain when you need to turn on BSP and define paths. For now just check geometry and lighting and hit the build key. See the 3d view now, this is how it will appear in the final level. Rebuild your geometry and lighting constantly to see what is happening to your level. NOTE: I hope you didn't forget to place a player start and a light in the room!.

(c). SAVING AND PLAYING: Time to save this baby. Hit file|save and in the save dialog save the map with an extension like DM-Delete. All death match maps will be in the format DM-xxx (where xxx is the map name), domination maps must be saved in the format DOM-xxx, Capture the Flag maps must be saved as CTF-xxx and Assault maps must be saved as AS-xxx. Now save the map as DM-Delete for now. Hit ctrl+p and UnrealEd will automatically launch and load the map for you.

THE CONCEPT OF INTERSECTION AND DEINTERSECTION

This is an important concept of the UnrealEd that you would do well to familiarize yourself with. Think of them as different types of scissors that you use to cut away the brush. Lets see how to make use of these concepts. Begin a new level by hitting the new level button. Lets build a room that has some beams running around the room at the top of the ceiling and that has a user made table. First lets build the room, create a cube height=512, width and breadth = 1024 and subtract this from the world. Now build a cube 64*64*2000 this is going to be the beams for you wall. What did you say? yes yes the beam happens to be larger than the room lets see how to rectify this. When we knew the measurements of the room why did we use a larger builder brush, well this just lends to efficiency and you are not going to know the exact measurements of the room every time. Now choose some wood texture (Nalicast.utx has some nice one under the Panel subclass) and lets create the beam. Now since the beam is larger than the room how do we shorten it?. Hit the deintersect button [ [image]] (just below the subtract button) or hit ctrl+d or go to Brush*>Deintersect, what happened now? the brush got shortened automatically to fit the room. Now hit the cube button and the intersect button [ [image]]and see the shape that you get. After checking the stuff out we can say that the intersect button is like taking a pair of scissors and leaving only those outside the cube cutting away those inside the cube and the deintersect button cuts away everything that is outside the solid leaving only that part of the builder brush that is within the solid cube. Take a look below to see the various states:

Lets see another function of the intersect button. We can create a complex shape using separate brushes and by using the intersect button create one single brush out of these separate brushes which can then be added/subtracted anywhere. Lets create a simple basic table to get the feel of this:
1. First lets create something we will call a building box. Frankly speaking this is something that you need to make for every level. You will always need to create complex shapes which you will do in the building box and then place in the level. For now lets create a cube the size of 1024*1024*1024, place this somewhere off to the side (usually at the very end of the level) and subtract this from the world. This will be called the building box and its texture does not matter.
2. Lets begin building the table. First build a basic table and texture it accordingly. I just made the table out of three cylinders - the table top was a big cylinder with a height of 20, the base was a smaller cylinder and the thing that held them together was just a cylinder on its side. This is how it looks in the various views:

3. Now just build a cube (it could be any primitive but its easiest using the cube) larger than the table and hit the intersect button. Viola you have a brand new brush that has taken the shape of the table that you just made and made it into one single brush. it looks like this:

Now you can just move this new brush around your level and add it in where ever you want to.

CONNECTING TWO ROOMS & COLORED LIGHTING

Well we got a bit deviated by all this intersection/deintersection stuff. Lets load up the previously saved map now and try to connect the very first room that you made to another room. Ok now build another cube of size 512*512*512 and place it some distance away from the first room doesn't matter how much and subtract it. it should look like this in the top view:

NOTE: This is as good a time as any to try this out. Say you want the second room to be the same size as the first room. Just select the first subtracted brush so that it is highlighted in yellow and from the edit menu choose duplicate (or hit ctrl+w). You will see a exact copy of the first brush with all the textures etc in place!. Now just move it to the desired position of the second brush. You will notice that the second room has not appeared in the 3d view because of the duplicating process - you will need to rebuild geometry to see the second room. Now build a brush 256*256*some value larger than the one separating the 2 brushes. Place the brush like I placed it in the picture given above, intersect and subtract and hey there two of your rooms are connected (unlike the drudgery work you have to go through to connect two rooms in other editors). Ensure it is in line with the two floors of the two rooms in the side view as well. Look what we have:

Now time to make the two rooms look better by using some nice colored lighting effects. First select the two lights that we place before (either right click on one light and hit "select all light" or hold down ctrl and click on both the lights) and delete them. Now add in fresh lights - about two lights in each room and one light in the hallway. Lets just make them red for now. Do a select all light again, now either right click and choose light properties or hit F5 or hit this button [image]. When the light actors properties sheet opens up, double click light color to expand it like this:

Hit the small button called color that you see there, the standard windows color chooser appears either select the default red or drag the slider to get the desired effect (hey you should be able to figure how to make your own custom colors out right?). Hit ok and close all open dialogs. Now its just a matter of rebuilding lighting to see what the level looks like now. Hit the bulb icon now and when the level has finished rebuilding the lighting see whether you like the effect if you don't you may need to adjust the light brightness (decrease the value for the all the lights. NOTE: LightHue is the actual color wheel number for that color, LightStauration determines how much the surrounding textures reflect that light. This is how the level should look like at this point:

It does look a bit different from the default red that you would have got. I always set the color like this - I first pick the basic color that I want to use, see whether it suits the level (as it so happens it doesn't suit this level) so I change the brightness and saturations numbers. There is no need to set light hue again as we have already picked the color that we want to use. In the above example I set all the colors brightness to 40 and light saturation to 160. You need to really practice the art of colored lighting to get it right and as I said before it is very important to make a good level. So use it wisely. Now rebuild the whole level and enjoy it!.

That's the end of this introductory tutorial. I really hope that you were really able to grasp the fundamentals of the topic. I suggest that you go through the tutorial at least a few more times. It will be a lot better so that you need not ask stupid questions on forums and get laughed at. Have as good a time making levels as I had writing this tutorial. If you have any questions you can always email me. Have A Fun Time Editing! and be sure to check out the rest of the tutorials on this site.


Level Design Tips For Unreal and UT

By: Oliver Gerestein

ogerestein@unrealkingdom.com

Unreal Kingdom

Designing levels for Unreal and Unreal Tournament is not just a pastime for me, it's also a passion. And just like any other pastime or passion, the entire process from idea to finished product is a long and arduous one: it requires an investment in time and effort, but one we all know is worth it. There are ways, however, to make the designing process much quicker, and therefore less painful.

This article is not geared specifically towards newbies and rookies, but rather towards established and somewhat experienced level designers who wish to refine their craft. To them, I propose a designing method which I have developed through my own experiences. The purpose of this is to suggest a step-by-step, efficient approach to level design, an approach which I now swear by.

1. A good idea

I don't think I have to tell anyone that every level starts with an inspirational idea. To my knowledge, a level is never the product of planned brainstorming or discussion groups.

For every idea I have about a level, there's a whole selection process that goes along with it.

  • has it been done before? If no, good! If yes, how can I improve on the idea?
  • what original features can be placed in the level?
  • is it feasable given the limitations of UnrealEd?

Ask your friends for advice. Most of their ideas are horrible, but some are worth considering.

2. Concept sketches

Once you've settled on a suitable idea, it's time to put it on paper. First, draw up some rough sketches to get a good idea of the design you're going for. This is often a good way to tell if the level is do-able. Show your sketches to some friends, and ask them what they think.

Rough sketches are one thing, but one of the most important steps in level design is the detailed sketch. This sketch should basically be an exact representation of your idea, with as much detail as possible. Emphasis should be placed on proportion, proportion and especially proportion. If your sketch isn't to scale, it's worthless. Be sure to include all movers, important items, and respawn points.

At this stage, you should review the sketch with a critical eye.

  • how is the flow? Are there too many dead ends?
  • how will the lighting work?
  • what is the ideal player load, and is it too big or too small?
  • will some areas be really choppy?
  • will the bots be able to go everywhere?

3. The level skeleton

It's time to start editing! Yay! Grab a beer and fire up UnrealEd, then go take a nap while it's loading.

First, you must build the skeleton. Essentially, the skeleton is an exact translation of what you drew on your detailed sketch, minus all the little things. To sum it up, it's just walls and textures, that's it. Once again, proportion is the key. Do your best to be faithful to the detailed sketch, it'll save you alot of trouble later on. A short note about textures: don't fix them later, fix them now!!! There's nothing more discouraging then having to go through a thousand-plus polys fixing texutres because you didn't bother to fix them as you went about building. Besides, it gives you a good idea of the interaction between texture and architecture.

4. Lighting and textures

Once you're satisfied with the basic architecture, it's time to do lighting. In my opinion, this is the most important part of level design: it makes or breaks a level. The lighting should suit the mood you're trying to create, for example, in DM-Warehouse, I wanted a dark, gloomy, inner-city atmosphere: fluorscent light bulbs indoors, a garbage can on fire outside...

A good tip: go nuts on spotlights. Even if you don't need 'em, use 'em. Don't forget that the spotlight only shines in one direction, so you'll need a radial light (the default light) to light up your lamp or light bulb.

Lighting is one of those things you can never be entirely satisfied with. Keep improving and changing your lighting, and do it instead of changing your architecture or textures, whenever possible. Also, make good use of coloured lighting and light effects, but don't go overboard. No one I know lights up their house entirely in green and red strobing searchlights, so don't do it either.

5. Adding detail

I should mention at this time that it's good practice to make backups of your level as design progresses. Everytime I add something significant, like lighting or a new structure, I make a backup. Later on, if I get a jumbo BSP cut I can't get rid of, for example, I can always go back to my latest backup instead of banging my head on the coffee table.

Adding detail is more important in single-player levels, but it shouldn't be neglected in multi-player levels either. Detail is meant to fill up empty corners and soften the hard edges in your level, but without being obstructive. Again, consider the flow: that's a nice crate, but now it takes ten minutes to get from A to B...! Details are nice, but speed and flow take precedence. Never add details at the expense of making the level much more choppy. Some would argue that the Warehouse has too much detail in the big storage room. However, some would argue otherwise.

A note about meshes (prefabricated 3d models): if a mesh is onscreen, no matter how far you are from it, the Unreal engine will render it in its entirety. When many meshes are onscreen, you can see the effect this has on framerate. Avoid putting lots of complex meshes out in the open.

Start thinking about sound. First, add music, but make sure it fits the atmosphere. Some of the finest user-made levels out there don't have a soundtrack, and it takes away so much. Sound should be used to add realism, and should not be a "feature" by itself. Look around your level, and add sound to anything that produces sound in real life (fire, water, traffic, echoes, water dripping, crickets, crashing waves, etc.) However, event sounds are just like any other detail: don't go overboard.

6. Item and weapon placement

Sadly, item and weapon placement is often done hastily. Think about it: there is little or no incentive to explore the level if all the good weapons are in one spot. Some tips:

  • spread out your weapons, so as to encourage people to go everywhere in the level
  • give players enough ammo!
  • go easy on big-ticket items like armour and invisibility: one each per level, maximum.
  • never ever place the Damage Amplifier right next to the Redeemer. Ever.
  • don't make secret areas no one'll ever find in a hundred years.
  • "context" your weapons: put the rifle up on a sniper perch, and the rocket laucher near an open space.
  • don't put too many weapons in dead ends.

7. Bots

You can't have a level without bots, it just isn't done. The way you should proceed is to place your botpath markers so that they form a coherent path through the level. It's okay to loop past previous paths, as bots can switch from one path to another to get somewhere they want. Make sure the markers go everywhere, because bots should have the same access to weapons as players. Don't forget to place jump markers and ambush markers where applicable.

Once this is done, play your level on spectator mode, and watch the bots from their perspective. See where they go and where they don't go, and if there are some jumps they can't make. If you notice one area of the map is busier than another, it might be a sign to change some item or weapons placements, or to add another entrance or exit to that area.

8. Beta testing

Never ever do beta-testing all by yourself. It's much like proofreading, in that the author, being attached to his or her creation, often overlooks some details that might seem obvious to anyone else. Gather your posse of friends, and let them try it out. Take their opinions seriously, as these are the people who will likely play your level later on and spread the word.

The main things to consider when doing beta-testing are the flow and the bugs. Some more tips:

  • make sure all the movers work correctly.
  • make sure you can't get stuck anywhere, even by accident in the most improbable area ever.
  • make sure you can get to anywhere in the level.
  • check the textures to see if they're properly aligned.
  • if it's too choppy, see what useless detail you can scrap.

Once all this is done, you've completed the level! But the work doesn't stop there...

9. Getting the word out

So you've toiled incessantly making the greatest Unreal level in the history of the universe. Might as well share the wealth, eh? Every level designer likes to get credit for his or her work, and getting positive feedback is really encouraging.

The biggest thing is to include a text file with your level. Even nowadays, some people neglect to do this. I encourage you to make use of the standard text file template, as it includes all the information others need to know about your level (all my levels include a text file based on the standard template: feel free to inspire yourself from one of them).

Then, design a web page, or better yet, have someone else do it. Since I'm inept at web design, my good pal Greg Rochon put together this professionally-looking site in his spare time. I provide the content, of course, but all the rest is Greg's handiwork. You should also consider having your web page hosted on an Unreal fan site, such as Unreal Kingdom. These outfits are often keen to recruit new sites to host, and offer unlimited webspace and bandwidth, all FREE!

Also, it's a good idea to submit your level to NaliCity and Fileplanet. These high-traffic sites are a good way to get exposure, and they also offer mirror sites and download counters.

So, with that said and done, good luck to all on your level design endeavours!

Oliver Gerestein
 ogerestein@unrealkingdom.com


The Art of Balance

By Trevelyan

Presumptions:

That you are at least an intermediate at UnrealED. This is merely a helpful tutorial on how to make your map as balanced as possible. I will also explain which weapons are best for whatever situation.

First off, let's look at the weapons and powerups that are placed within your map:

Chainsaw:

It is seldom that you see a chainsaw in a deathmatch arena; if you are in the heat of a deathmatch and you decide that a melee weapon is better than a rocket launcher, then have fun dying. In other words no one wants a chainsaw, so don't make it a crucial pickup in your map.

Enforcers:

Again, not a great pickup to have within your map either. Note that adding a "double enforcer" does nothing when added to a map; simply adding an "enforcer" will allow a double-enforcer to be used. A personal preference is to occasionally add an enforcer directly on a playerstart, giving the player more of an edge against spawn-killers.

GES-Biorifle:

This weapon is suitable for small corridors and the like. Also consider placing the goo-gun in high altitudes, allowing you to shoot downward at your opponents. Ammo for this gun should usually be close by, as running around for ammo for it tends to be a waste of time.

AMSD Shockrifle:

One of the 3 weapons that must be spaced out between them to allow a balanced map, this weapon needs to be placed very carefully. Too much ammo for this weapon will force your map to become a "shock arena", and take away from it in time. Use Epic's levels as an example of good AMSD placement. In Liandri for example, there is only one AMSD, and collecting ammo for it requires a tricky jump, or wasted time climbing up that ramp. A good setup for placing this gun usually has the AMSD with one shock core, with other shock cores in other spots in the map.

Plasma Rifle:

This gun is most suitable for wide-open areas, although the gun can be placed pretty much anywhere for a desirable effect. Ammo should be somewhat plentiful, even if running out is actually pretty rare.

Ripper:

Definitely place this thing in a place that allows the gun to do its best work: Bouncing around corners. Try not to have the players attempt to defend themselves in wide-open spaces with only the ripper. (It can be done, but it's not a fun situation ;)

Minigun:

Personally, I loathe this gun due to a constant 300 ping. However, whenever a "good marksman" is ripping me to shreds (read: LPB) I notice it's in rooms that are rather large, but not wide-open. It's really a weapon that can be placed anywhere, however, so not much else can be said on it.

Flak Cannon:

Another of the 3 weapons that must be spaced out between them. The flak cannon is rather versatile in the hands of a good player, so placing it wherever will work fine. Just make sure that 1: Ammo is tough to find for it, and 2: Getting the gun itself is somewhat difficult.

Rocket Launcher:

The last of the 3 weapons to space out. It's definitely the most versatile weapon in the game, so place it in an easy to reach location that attracts attention. Ammo must be very sparse on this one; you should have to walk through the whole map just to load up on ammo.

Sniper Rifle:

Place this in a corner of the map that allows you to camp while firing at unwary opponents from afar. It sounds cheesy, but this attracts anti-campers to the same location, creating a nice level of complete havoc.

The Redeemer:

I would classify this one as a power-up rather than a weapon. Remember that your map can be ruined with just wrong placement of the Redeemer, and that you don't have to place it in your map at all if it makes it unbalanced.

ShieldBelt:

Never, ever have more than 1 shieldbelt in a map, unless it's a CTF perhaps. Make it a challenge to acquire if possible. Deck16 makes getting the shieldbelt a real hassle in a crowded match for example.

Damage Amplifier:

This thing is widely considered to be cheap. And any map that doesn't have it in there will not be considered a bad thing. If you do place it in your map, make it extremely difficult to acquire! A good idea would be to make it accessible only by a piston-jump (like in Liandri, Malevolence and Turbine) so that the bearer at least will take damage for his covetousness.

Invisibility:

In Unreal this pickup was beyond the realm of cheap. In UT this pickup is not very useful. In fact, in team deathmatches it causes team kills and "pushes"! Therefore, don't go nuts trying to perfect the placement of this one.

Jump Boots:

Not always a necessary addition to your map; really, it's all up to the mapper as to weather or not they want boots in. The primary purpose of the boots are to make a map more accessible if need be.

Keg O' Health:

Not much to say here except that you should place this away from any other health pickups; and of course not to place it too close to any other powerups.

Body armor and Kneepads:

Space these armors away from other powerups, and try to get both armors to be as far apart as your map can handle. Do not put more than 1 of either armor in your map either, unless your doing a CTF map.

Health vial and Health Packs:

Don't overdo either of these. Health vials are good for being near spawn locations, as it's a bit of a boost. Health Packs should be in pairs of 2, and spaced out throughout the level. Don't let an injured player heal up quickly due to bad health placement.

Other notes on balance:

Connectivity:

Your map should have a "flow" to it. Many people dislike the use of doors in a deathmatch arena; do to the fact that it interferes with the players running through the map. (Also, doors are a pain when you have a high ping, due to the lag time of them opening.) If you do have doors within your map, try to use triggers to open the doors, grocery store style. There should be a flow through the map that makes you come in contact with most of the weapons, and come in contact with your opponents. Never put dead-ends in your map, and try not to make too many deadly pitfalls either. Lastly, depending on your map (since it's purely a matter of taste) you might want to create teleporters that allow you to run through the map easier, instead of backtracking.

Spacing out your weapons/powerups:

Do not ever place the most powerful weapons (AMSD, Flak Cannon, Rocket Launcher) within close proximity! You want even the most experienced player to run throughout your map in order to kick some @ss. The 2 most crucial elements are the Flak and RL being spaced far apart, and the Amp and Shieldbelt being spaced apart. And try not to place too much ammo either.

Secrets:

Secrets are fun to create; but much care must be taken when implementing them. Remember that most players eventually know all secrets in a good map; so the secret's contents mustn't be too rewarding. (For example, don't make a secret contain a shieldbelt, amp and mega health in one spot.)

Playerstarts:

Personally, I generally place precisely 16 playerstarts in a map to avoid telefrags at the start of a crowded match. However, some maps are very small and require less. Remember that most maps never have 16+ players going at once, and too many playerstart actors can cause annoying misbalances. Don't place playerstarts in midair, no matter how cool it is. The reason is that if you hold the crouch or walk key when you spawn in midair, you will remain there until you let go! The same applies for teleporters also. Lastly, Make sure that there is a weapon near every playerstart. There are few things more frustrating than spawning and looking around all day for a weapon.

I do believe this covers most of the bases on balancing out your map. I may be wrong on some subjects due to a matter of taste, or that a special design on a map would permit something that normally wouldn't. I do, however, hope that this guide will help you out.

---Until next time---

Trevelyan


Common "In Map" Problems

Common In-Map Problems

By Trevelyan ( connors@nnex.net )

Presumptions:

None. This is a guide to many problems that maps have, particularly ones made by beginner/intermediate UnrealEd'ers. I have also added in a few quick notes on how to balance the map out, but I also plan on adding another tutorial based solely on that. First, there are the basic technical problems that many maps have; BSP problems, and HOM effects.

BSP HOLES:
If you are already into making maps, this is your worst nightmare. I remember my first BSP cut; I'm testing out my map as usual, and I go near a wall. The wall disappears. I die instantly for no reason. I respawn, and the wall is intact again. Welcome to the world of BSP.

What's the problem?
I won't lie to you. I have no clue as to the technical reason of what happens when BSP problems occur. What usually causes the problem though is sloppy use of brushes when placing them in your map. A big problem arises when you intersect or de-intersect a sheet when using them for zone portals. When you use the floor lofter incorrectly you will almost certainly see some kind of problem there also. When you are making hallways by subtracting brushes, and don't intersect them first, again you see this kind of thing. Basically, impatience is the cause.

What's the solution?
Be patient when creating your map. Don't go nuts with the subtract key, and make 10 hallways in 15 seconds! Always intersect 2 subtracted brushes that meet, and always de-intersect 2 added brushes that meet. When faced with an "invisible box", a solid invisible obstruction, save your map and slowly eliminate possible culprits. (Maybe that sheet? That crate? Experiment!)

HOM (Hall Of Mirrors)
This is everybody's favorite (sarcasm) effect in the whole wide world. Ever get stuck in a hole or wherever, and every frame in front of your gun remains pasted onto the last frame? (Hard to describe, but you have probably seen it before)

What's the problem?
This one's easy. When you create a map, you remember seeing that blue grid that represents space? Well if you see this nothingness in the game, this is what you see instead. If you make a surface transparent, and nothing is behind it, these will occur easily. Another cause is a mirrored surface reflecting onto the skybox. At certain angles you will get the praised HOM effect there.

What's the solution?
Not too difficult here. Just check out what you are doing more closely. You might have just highlighted the wrong special effect when selecting a surface.

PATHNODE CRASHES:
Ugh. Pathnodes are seldom fun to implement. If you get a bizarre crash when testing (or god forbid playing) your map, where the bot stands still for a short period of time before the mighty boot occurs, the solution is simply to Define your paths. Check out the tutorial if you're confused on that one.

FRAMERATE PROBLEMS:
Slow as molasses when taking on that 35-story tower? Look no further!

What's the problem?
Easy explanation: Too much stuff going on in the screen. Better explanation: Too many polygons, too fancy lighting effects and un-optimized terrain. (Especially outdoor scenery, check out that tutorial for more info)

What's the solution?
Check out some of the maps in UT for examples on how to "cover up" terrain to speed up your frame rate. In CTF-Lavagiant, for example, the mountains in-between the 2 forts not only are made up of only maybe a couple-dozen polys; it also blocks out visibility between the 2 more detailed fortresses. If that mountain weren't there, the game would have a terrible frame rate. (Not to mention suck!) Go easy on your effects too. When using fog, for example, make sure it's within a small room, out of sight of larger areas that boast a large polygon count.

LITTLE THINGS THAT ARE HARD TO ACCOMPOLISH:
Here's a list of things that seem impossible to do to a beginner at UnrealED. Other tutorials have these, but don't list the little things that make it actually work…
Creating fog: You need a zoneinfo (under classes> info> zoneinfo) within the room, and simply adjust the 3 volume settings under any light actor in that zone. The zone must have "bFog Zone" set to ON, and the magic part: You need to rebuild geometry for you to see the effect.
Screenshots: Mentioned in the screenshot tutorial also, just a reminder to get your screenshot saved well:
1-DO NOT USE MS-PAINT in any way, shape or form! The picture will come out terrible, I can assure you!
2-Rebuild geometry once you have properly imported your bitmap. Then save your work. If you don't do this, your level will be terminated! (Well, actually, the data will still be there; you just have no access to it in any way. ;) Also remember this if you are importing music, or anything for that matter.

IRRITATING TIBITS:
Here is a list of many things people hate from some mapmakers:
-Overuse of messages: Don't add 10'000 messages in a death match arena. People want to fight in an arena, not read all day. A novel effect indeed, though, but the novelty wears off sooner or later. And then you are left with 10'000 boring messages while you fight.
-Bad weapon/item placement: Don't ever, EVER place all of your power-ups in the same location. DM-Pressure is the only notable exception to this rule. Make your power-ups/weapons spaced out in order to make the players run throughout the map. Stuff like the amp and shieldbelt should be difficult to obtain.
-Half-assed maps: Stuff like texture and brush alignment are paramount in order to create a realistic environment. Never skip the little things in your map; create screenshots, add music and eye candy. Just making your idea alone and sending a "nearly finished" map to people is a bad idea. (Unless it's to something like UT City; then obviously you would want to!)

Thank you for spending your time with my tutorial. I would like to create a FAQ on this subject, but don't seem to have many people asking my any FAQ's! If you have any questions on UnrealED, E-Mail me at connors@nnex.net. Later.


Basic Construction Phase 1

Knowledge in Depth

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

Forward

Well, here goes a new tutorial. This tutorial will certainly be a lot longer then the others, as I will be going through the making of a whole level from start to a point where you should be able to take over and finish it off.

While the level will be fairly basic, and not something that would win all the prizes at a contest, it will be a good way for you to start Unreal Editing. In these tutorials, you will find that I explain everything I do, and I will also track each thing with the most detail I can (Without going over the top).

I have been receiving a fair amount of mail asking for things to be explained, and I will be trying to get to the level of detail that some of the visitors ask for. If you find that I am getting too bogged down, skip to the next bit, or ignore a sentence or two, but all in all, this should be a perfect guide to getting you not only started in the editor, but also making maps in general.

Abstract

I will be making a DM (DeathMatch) level here that will have a few nice goodies in it, and it will include heaps of things that people ask about. I will be offering downloads of the map in it's building stages, so you will be able to find out how I go about things, and what I have completed in a certain tutorial.

I will also be placing links in this tutorial, to other tutorials that cover either similar areas, or things that may interest you. Please don't get too bogged down in reading the other things, as I will be explaining everything here, and only offer the other links as things that you may like to read at the time, to either get a better understanding of something, or to show you a place where you might find something that takes things a step further. In any case lets get this thing on the road eh?

Assumptions

In this tutorial I make no assumptions. It is a tutorial aimed at a beginner who has very little understanding, of the Unreal Editor, or someone who may have a decent idea of Level Design, but has little experience in UnrealEd.

Note
Unlike the other tutorials, this is not split into small sections with headings. It is however split into paragraphs that should be read completely before you get into the editor. When you finish reading the paragraph, try to go into the editor and do what was written without looking at the tutorial all the time.

This will help you to remember and more importantly understand what I am writing here.

Firstly (and most importantly) you will have to open the editor.

If you get an error like 'Unexpected Error 50003' or some other error that won't let you open the editor to a normal screen, please head over to unrealed.net to attempt to solve the problem. Files that may be required to make the Editor work can be downloaded from the site, under the ‘Files’ section of the site.

If you have got the editor working, please proceed.

When you open the editor, this is what you should see. If you have used things like 3DMax or Lightwave etc, then it will most likely be quite familiar; otherwise, it will most likely be quite daunting.

Actually, it's a good setup, and I will take a few moments here to explain what each thing does.

In the left-hand side, you will see a menubar of sorts with heaps of little buttons on it. I will not explain here what each of the do, as it would be a little like saying things over and over, but unrealed.net does have a tutorial that does explain each of them and the Ued Help File also covers each of the functions. Take a look, and then come back. I will be explaining things as I go here anyways, so don't get too caught up in it. It will be made clear in this tutorial anyways.

Next there are four windows that have a specific task each. They are windows that you will be using to view your map as you make it.

  • The top left one is the over head view. You will see your level in an architectural design here. It will be filled with lines, icons and all sorts of good things by the time we finish here.
  • The top right hand one is similar. It is the 'Map XZ' screen. This means that it basically takes a shot of your level from the front. It is also something that shows your level in 2D, using different colours of lines etc for different meanings.
  • The bottom right is once again a 2D view. This time it shows your level from the side. I could say left or right here, but the easiest way to explain from which side is this. In the top view, as things get further down, then they will appear to go towards the right hand side of the side elevation. Got that? It's a little hard to explain, but you should either get the idea now, or you will as soon as we start to make things, and use the screen to work things out.
  • Ok, there is a nice black screen left (Although there should be a few dark blue lines in it). This is the 3D view. It will be an invaluable guide to how your level looks, as it provides you with your window to the world in a rendered fashion. You can move through there and do almost anything you like. It's like having a little player move in 'Ghost' mode while you are playing, except you will also see where you have lights, icons, and how things work.
Lastly, there is another toolbar on the right hand side. This is what is most often called the 'Textures Bar' or 'Browser Bar'. It is where we select textures to use, classes and actors to add, and all the other cool things that we will be using.

Once again, I will be explaining this one as we go on. Trust me, the last one, there is a LOT of explaining to do with, so I will be making the most of it, but rather then say it all now, I know that you are getting anxious to get into the real editing right? Cool, so am I =) It's getting a little boring just typing all this in, so let's start on the level itself. More will follow on these screens when we need to use them ok?

Now the first thing that will be needed here is a texture style. I will be making this level in a 'Natural' style, and there will be a few areas of a simple village in it as well, so I will be using textures that come with the Unreal engine (Rather then making my own so early in the level).
If you haven't taken a look at the textures before, you may want to have a browse at what is available, but I will be making notes of each textures names as I use them. This will make it easier for you to make your level to the exact thing that I have done here. Ok enough banter, the first texture package that we open will be a set called 'Ancient'.

In the editor, on the Browse Bar, you will see a button called 'Load'. Here is a quick image, if you are having problems (The middle is cut out to make it smaller).

I have got a few steps here with nice blue numbers. I will be using these as a reference to what I am talking about. Ok, here is the list of what each one does...

  1. This is the folder from where you are opening the file. Most of the files that you will use should be located in the 'Unreal/Textures' folder, as this is where they will need to be so that when you go to play the game, it loads Ok, and the other machines knows where the files are.
  2. This is a list of the various texture packages that you have got on your hard drive. If you don't have all the ones that you see in my window, relax, as I have got quite a few that I have made, and I have also got others downloaded from the net, or packaged in files with maps in them. If you installed Unreal, you will have everything that you need.
  3. This is where the name of the file that we are after will be. It's very much a normal window, but I may as well explain it in detail right? That's why you are reading this tutorial =)
As you see in the image, click once with the left hand mouse button on the file called 'Ancient.utx' and then press open. It will automatically change the look of your browser bar somewhat. All it has done is simply loaded the current images to your bar, so that you can access them easier. Keep in mind that when the editor opens, all the textures that are loaded are not for actual use in the game. They are only there for the engine itself, and so that you can see what you are doing in the editor. You should under no circumstances actually use them in a level!

Now that we have our textures open, we can start to make something in the world. The first thing that we will make is a rough corridor in a mine. It will be where the player starts off, and I will make it fairly basic, but not the usual 'Square' corridor that so many people make, which is such a let down. Here goes...

Now we want a corridor that is large enough for the player to stand in easily, but also to make a slightly 'cramped' feel of a mine, so here are the sizes that we will need.

Height = 128
Width = 96
Breadth = 256

These are roughly large enough for the player to stand in, but will be tight enough to make them feel pressed in. 'Ok, where do those wonderful numbers go?' I hear you ask? Great, showing signs of initiative. Cool Bananas =) Right click on the 'Cube' primitive. This button looks like this:

Now you should see a nice little window that is open. it will have a lot of fields that you can enter information into, and you will use these fields a LOT of the time. It is much better practise to get used to entering the number manually, rather then stretching shapes and scaling brushes (All explained later).
When you enter the number manually, you not only know the exact size of the brush, but you will be able to control it better for texturing, and that is something that is VERY important.

This is what you should have. Enter the number in the fields as I have done, and then press the 'Build Button' to create your shape. In the windows of the editor, you will see a nice little red rectangle that has been made.

You will use this red 'Builder Brush' to create your level with. It will never actually show up in the game. It's a little like having a template of sorts that creates your world with little stamps. You can change, shape and do just about anything with the Builder Brush, then when you are ready to use it somewhere, you will actually 'Stamp' it into the world, and only then will it actually be made into the level. If that's not quite clear yet, just keep following, it will get quite clear very soon.

Press the 'Close' button on the 'Build a Cube' window as we no longer need it. You will still have the Builder Brush there, and that's what we will now use. Before we cut the brush from the level though, we will need to select a texture for it right? If we don't select one now, we will have to manually assign a texture to each surface, and that takes more time. For the mine corridor I am using a texture called ABasic4. It is a nice 'rocky' and 'earthy' texture that will be perfect for what we need.

Now press the 'Subtract' button to actually stamp the Builder Brush into your level. The 'Subtract' button looks like this:

The main difference that you will see is that in the 3D window, you will now have what appears to be a small corridor. Let's move the view so that it is where we can see it more clearly. Move your mouse over to the 3D window, and press the Left mouse button. It will allow you to move the screen like person running about in the world. When you hold down the Left Mouse button and move the mouse, you will be able to move forwards and backwards. You will also turn left and right. Now, hold the Right Mouse button down, and move the mouse. You will see that the view moves about. It doesn’t actually move your position though. All you are doing is moving the view about. It's like simply moving your head to see what is around you, without actually walking anywhere. Now, hold down both buttons, and move the mouse up and down. You will see that your level moves up and down. This is like basically standing in an elevator that you can control. Nice innit? Have a little play at moving about, as I won't really be going over it again for the 3D window. It's really easy to catch on, and I don't want to spend more time on it then that.

Now that you have got the idea behind moving in the 3D window, move your viewpoint (Where you are looking FROM) so that you are looking down into the corridor from one end. It should look like this:

Cool. You have just made your very first corridor! Now while you cannot play the level yet, you have just started out in level editing. Trust me, it goes downhill from here =) If you have gotten to this point, you should find that things get easier, and more fun as we go on. The hardest thing is to actually start out.

Once you have started, things get more and more enjoyable, and therefore easier. Right where were we? Ah yes, the corridor. Now we could leave it like that, but it doesn’t look like a real mine corridor yet does it? (Well, not by my standards yet anyways) so let's make some alterations to it...

The first thing that stands out to me, is the lack of supports in the corridor. I mean have you ever seen a mine without supports? Ok. For the next step we will need a small construction area. I use these all the time, as they make life so much easier, and make the level less messy, and in general better built. The idea is to simply have a nice large area somewhere in the level that is used for the creation of shapes, and other things, which will be deleted just before the level is released. This allows us to be messy while we build, and is generally a life-saver. Ok, right click the cube button again, and this time, change the numbers to 1024x1024x1024. This will create a large brush in a cube shape that we will use for our construction yard for a while (Till it runs out of room basically). Press the Build button again, then close the window.

You should find that your screen has now got a huge cube in it. Zoom out a little in the 'Top Down' view. To do this, is almost like moving in the 3D window. In fact, all the 2D windows have the same movement in them. Left Mouse Button OR Right Mouse button will allow you to move the window around, depending on what way you move the mouse, and holding Both Buttons down will let you zoom in and out. Play with it a little to get the idea, then zoom out a little in the window, till you get something that resembles this view:

Now to move your brush out of the way of our corridor, we hold down the CTRL key, and the Left Mouse button over the 'Top Down' view, and move our mouse left. You will see that the Builder Brush moves to the left (assuming that you move your mouse left).

Place it somewhere off to the side. The problem here is this. What if we want to move the object further then one screen? There are a few ways about it. We can zoom out, and have more area to work with, or we can take it in little 'hops' ie move the object, then move the screen to catch up, move the object again etc etc. The problem with zooming, is that we lose the ability to see detail, which isn't too important right now, as we only have one corridor there, but it will certainly make a difference when we want to align things to exact places, and when there is a LOT of things on the screen. On the other hand, moving the Builder Brush in little 'hops' is very annoying right? What if we wanted to move it 10 screens? That would send me crazy... (Yeah, I know, not hard right? Hehee).

There is another way to move things, but I wanted you to see that way first, as it is more often used (At least by me...). Hold down the SHIFT key, and the Left Mouse button, and drag the mouse over the Top Down view. You will notice that your brush is moving, but the window is kept in the same perspective in comparison to the brush. This is very handy. Please move the new large cube to the left of the corridor, so that there is a fair amount of gap between them. It should look something like this:

Now press the Subtract Key again. Here is a little image in case you forgot what it looks like.

Don't worry about textures or anything like that, as it will never be in the actual game itself, so it's not important at all. There, you will now see that we have got a nice large area to work in, and create new shapes right? Cool. Lets make a support brush for the corridor to have in it. First things first again. We will need another texture for it, so on the Browser Bar, click the 'Load' button again. This time, open a package called 'Nalicast.utx' It has got a few good wooden textures in it. The one that I have chosen for the support beams is called 'T-Wood'. It good as it is very nice, but also dirty enough and seems to be covered in dust - Perfect for a mine right? Half the fun with designing levels is to find the right textures that will make your job easier. The better a texture is, the more realistic the level looks, and that's what it's all about.

Now create a cube that will become one of the support beams. Make it:

Height = 128
Width = 16
Breadth = 32

Now press the 'Add' button to add it into the world. This is different from the subtract button. The button looks like this:

The reason that we are adding this time, is because the place where we want the brush to be inside has already bee subtracted from.

    Quick Lesson in Editor Workings
    The world in the editor when you first open it up, is actually a huge, great area that is SOLID. When we want to make a corridor for example, we 'Cut' it from the world. When we want to place a brush into something that we have already cut out, we have to 'Add' it back into the world. This may seem a little weird at times, but it certainly is a LOT easier then working with a world that is hollow. All we have to do is cut a corridor from the world, and technically, we could go running through there right away. It may be a little hard to grasp at first, but should become second nature by the time you finish either this tutorial, or the next one in this series.

Great, now with that out of the way, proceed to add the brush if you haven't done so already. Cool, that will be one of the side beams that the top one will 'rest' on, and support the heavy world above it. In fact it's completely not needed, as we can do anything here, We could make a entire city stand on a toothpick, but it will add to the realism of your level, and that's what counts. Now, changing the size of your cube again, make a brush with the following sizes:

Height = 16
Width = 96
Breadth = 32

Press the Build button (It should be starting to get second nature to you shortly) and then close the window. You will see your Builder Brush is sitting there waiting to be placed. Move it so that it sits on top of the first beam like the following shot.
Ha! I have been busted here. We have to do something else first. If you tried to move the shape about, you should have found that it will not let itself move perfectly to the place that we want it to be. This is perfectly understandable, as the grid settings are still too high. Forget the Builder Brush for a moment and Right Click in a 2D window. You will see a nice little menu appear. Move your mouse over the 'Grid' word, and you will see another submenu appear. It should look like this:

The default setting is 16 Units, and for many things that is fine, but in this case, it doesn't allow us to have enough control. Right, now you will be able to move your support beam (Still the Builder Brush) so that it sits nicely on one end of the other beam. It should look like this:

Pressing the 'Add' button will once again, create the Brush into something that will be left there no matter what you do with the Builder Brush (Which is what we want). Now I will show you a little trick. You could create another brush that will be the same size as your first support beam, and place it under the other side of the support right? That would be reasonably easy, but let's just 'Copy' a brush over. There are a few ways to do it, but this will be the best way. In the Front Elevation (Map XZ) window which is the Top Right, Left Click anywhere not on a brush, so that nothing is selected, then Right click the bottom support beam so that it is highlighted, and a menu appears. It should look like this :

Highlight the 'Copy Polygons' and then left click the 'To Brush' option that appears. It will allow you to basically copy the Polygons that we made earlier into the Builder Brush without having to do anything else. When you have got the Builder Brush copied, you will notice that it has moved. It will be in the exact place as the first support beam that we made. This is normal. It copies everything to the Builder Brush, including location, which is where the brush is. Now, simply move it so that it sits nicely under the other side of the Top Support. Done that? Now 'Add' it in, like the others, so that it's there for good, and our support structure is complete.

Now for something a little trickier then what we have done so far. We will make ONE brush out of what we have got there. In other words, rathe then creating the support structure for each place in the mine, we will create a single brush out of it, so that it does a few things. Firstly, it will actually speed the level up a little when you are playing. It is easier for the Unreal engine to create one complex brush, then to create three simple brushes. This may sound like it's going over the top, but they all add up, and let's face it, we want the fastest framerates about right?. It will also make less errors in the editor (Hopefully you will not find them, but more then likely, sooner or later, you will come across something that isn't doing what it is supposed to, and the later we can make that the better.

Lastly, and perhaps the most importantly, it makes our life easier. The easier it is to create a level, the quicker we can do it, and the more enjoyable it is. So, trust me here (I do have a plan for all of this Tutorial) and let's create a single brush out of it. Create a new cube. This one will be 256x256x256. It's nice and simple, and certainly large enough to cover the entire size of the support structure. When you have created it, move it so that while it covers the entire structure, it doesn't overlap anywhere else (Like the edge of your original work area, if you have been building this off to the side) and then press the intersect button which looks like this :

Now you should find that your Cube has got the shape of the entire Support Structure(Ie, there will be a red outline of the entire three beams). If it doesn't, or only has half of it, then you will find that your original Cube didn't cover the entire three brushes. If so, simply press the cube button again (It will still have the size that you last entered in memory) and do it again.

Done that? Cool, you have just created your first Intersection, something that most people don't learn about till it's too late, and a few maps look and play very badly... Anyways, enough there. Now move your brush so that it sitting nicely inside your corridor at one of the ends.

What? Do I hear you say that it doesn't fit??? Ha! Did you think that I would pass up this perfect opportunity to teach you another thing? (I tod you I had a plan =) for this tutorial). Yes, The brush doesn't quite fit in does it? You will find that if you align the top support beam to the top of the roof, the bottom of the Structure sticks out 16 units.

This will be a perfect example of 'De-Intersecting'. A few moments ago, I showed you how to create a new brush out of solids that are already in the world.

Now I will show you how to 'cut off' unwanted bits of brushes that stick out too far, or are not needed. Note that this will only work when you are adding in a brush into a place where you have already 'Subtracted' from. Ie, you are going to 'Add' the brush in. When you have it placed nicely (Like in the screen shot I have got there) simply press the 'De-Intersect' Button to cut off what we don't need. The De-Intersect button looks like this :

It will effectively cut off the bits that we don't need for the support. Now we could simply 'Add' it into the world here and now, but that would be getting a little tiny step ahead of ourselves (and I have checked to make sure something bad will happen, and it does, so we have to do something else before our corridor is complete with Supports. Let's move our support Structure back over to the large work area that we have built.(The Large cube where we built the support in the first place).

Add it into the world there. Depending on what way your 3D window is facing, you may see what has happened. If you see the normal support, move the window so that you are facing it from the other side. You will notice that when we 'De-Intersected' the Builder Brush, it actually made one of the sides take the same texture as the wall. This is normal, and happens to anything that we Intersect, or De-Intersect. It is simply done to make our life easier, but in this case, it happens to work against us. Ok, easily fixed though. Simply Left Click on the texture that we want to change back, and Left Click the texture that we want to replace it with in the Browser Bar. It should still be T-Wood.
Here is a shot of what I mean.

This isn't something that we can avoid, but on the bright side, in most cases, it certainly makes life easier for us. (Just not in this one) =)

Now, make another Cube and intersect the new and improved Support Structure. Move it over to the corridor again, and place it to one end as before. Now, using the 'Add' Button, add it into the world, and you will see in the 3D window that it has been added, and it textured nicely like the one that we built from the three beams right? Great. Now, moving your Builder Brush to the right some more, make another support - near the middle of the Corridor. Add it in as well, and when you have done that, add in yet another one right near the other side of your corridor.

If that is the case, great, read on, otherwise, you will have to go back a few steps and work out what has gone wrong. It shouldn't have though =)

We are almost done with this tutorial for today (Or if you are really eager, till you load the next step) At this point, we would love to play it right? Bad News. The level isn't quite ready to be played yet.

We need to add in some light and also tell the editor where we want the player to start when they do. First things first though, let's add some light. In the 3D window, in one end of the corridor, right-click the mouse on a wall (Near the roof) and you will see a little menu drop down.

From the menu select 'Add Light Here' and you will see a little torch appear in it. Don't worry, this torch will not be seen in the game itself, just in the editor (Remember those textures that are loaded into the editor when you open it? The ones that I told you not to use? Well, this torch is one of those Textures. It's not something that we want to have in the game right?) Cool. That was easy. You have just added your first light to the level =)

Now all we need is to tell the editor where we want the player to start off. In the Browser Bar, you will see a word that says (Strangely enough) 'Browse' If you drop the menu next to it, you will be able to choose four things. We are interested in one of the at the moment. It is called 'Classes'.
When you Left Click it, it will open the Classes menu. This is where the real editing goes on. From here you can place things like PlayerStart’s (Which we are about to do) and a whole lot of special effects, not to mention all the important items that we will get to later.

For now though, left click on the little 'Minus Sign' next to the words 'Navigation Point' and you will see a subclass open. From here left click on the 'PlayerStart' class. You should now see it highlighted. Great =) Now in the 3D window, right click in the opposite end of the corridor (Opposite from where you placed the light that is) and you should see a new option appear in the menu that opens.

    If you don't see the option there highlight the 'PlayerStart' Class again, as something didn’t quite work out, and try again. When you see it however, left-click the option, and you will see a little joystick placed into your map.
There, almost done (I promise). There is one final thing to be done. We have to rebuild the level.

This is where the real work goes on. Press the F8 key. You will see a new window appear. For simplicity, I will just tell you to press the 'Rebuild Geometry' Button. This is assuming that you have not made any changes to it before right? If you have then just make sure that Lighting and BSP are selected in their respective windows. If you haven't ignore that last statement.

When it finished rebuilding (It should only take a few seconds) Choose Save (From the File Menu) and save the map as 'Phase_One.unr' (Without quotation marks of course). It's time to test the level out.

Open Explorer, and locate the File you just saved. (It will be stored under Unreal/Maps) and double click it (Click once if you have got Win98 with Single Click Option Enabled). You will find that Unreal Opens, and your map is loaded for you to play =). Congratulations, it's your first Unreal map, and it should look pretty damn good so far...

Here is a shot from my map:

If you got this far, see you in the next tutorial. We will add more to the level, and I will show you more techniques, and ways of working in the editor.


Basic Construction Phase 1

Basic Construction Phase One

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    Forward:

    I couldn't decide where to start, so this placed itself on the screen as I sat there.

    Abstract:

    This tutorial will cover what most people need to start editing within UnReal. I will go over basic steps to carve out a sample room, adding a few of the features, make it playable (although it would actually be rather boring, with just what we will do) and give you a good start. This is a fairly long tutorial, but it goes into detail that is sadly often missed by most tutorials for beginners.

    Assumptions:

    I make no assumptions here, apart from that if you have trouble with any of the terms; you should look up my Jargon Tutorial. Things in the jargon tutorial will be marked with *.

    Tutorial:

    Introduction:

    When you have loaded UnRealED you will see four main windows, a few buttons to the left and some textures* to the right. You will also see a red cube in the lower left window. Before we go there I will however explain what the views are. The top left view is the "Top Down" or overhead view. The top right window is the "Front" view. The bottom right is the "side" view. Finally the bottom left is the 3D view. The 3D view is movable to any angle by the mouse. I will start with the absolute basics.

    View Movement:

    To move in any of 2D windows, simply press and hold a mouse button and then move the mouse. To zoom in and out, hold both mouse buttons and move the mouse up and down. The 3D window is a little more complex. Holding down the left mouse button and moving the mouse will move forward and back, and turn left and right. Holding the right mouse button will move forward and back and strafe left and right. Holding both buttons down will move you up and down, and strafe left and right.

    Making the first room:

    Right click the cube button* (This brings up a menu), and select cube properties. There you will see five places where you can type. In height field enter 256. (It should be defaulted to this anyway). In the breadth field enter 512, and 512 again in the width. Now press build (you can shortcut this by pressing the "enter" key.) In the 3d view, you should have seen a change. Now go over to the textures toolbar* and click on load. This will bring up a load box with many files in it. Select "Ancient.utx" (One of my favorites) and when the file has loaded, scroll down the textures bar until you find a good texture for a wall and select it (Single click the texture). When you are happy with the Texture, hit the "subtract" button*. You should now have brand new room in your level. Now in the 3D view, highlight the floor (single click on it) and find a good texture for the floor (try the drop down list for "floor" textures - see textures drop down lists*) and single click it. This should give you a nice Floor. Repeat the process for the ceiling (once again, you can use the "Ceiling drop down list" from the textures). You should have a good looking room now.

    Adding the light:

    We need to add some light into the room to make it playable. In the 3D view, make sure you can see a corner near the ceiling somewhere and right click it. This will produce a menu - select "Add Light Here" and you will see a flaming torch added to your room near where you clicked. (Have a look at the full lighting tutorial for more info on lights and stuff - but do that later!). Now place another light in the other corner of the room and you should just about be ready to rebuild* - but there is one more thing that is missing, a place for your player to start.

    Adding the Player Start:

    Go to where you see "textures" at the top of the screen to the right, and select "classes"* from the drop down list. This should bring up a list of things with a line in front of them. Single click on the line in front of "navigation" and you will bring up a list nested in the first one. Select "PlayerStart"* and in the 3D view, Right click on the ground where you want your player to start. Once again you will see a menu come up - this time select "Add Player Start Here". You should now see a little joystick placed on the floor of your room. Now you are almost ready to play the level, just ONE more thing.

    Rebuilding the level:

    You now have to "rebuild" the level and this is !!VERY!! important. Press F8 (this sometimes seems to do nothing - if this is the case, then go to the top menus (File, edit ect ect) and select "Options" then "Rebuild" and make sure that the "autoBSB" is checked ( I'll go into this in a later tutorial) and press rebuild.

    Saving and Playing the level:

    Well, after all of that these are a piece of cake. From the "File" menu, select save ad give it a name, then when it has finished saving, select the "file" menu again and choose "Play Level" this should now bring you into the game from a players view. That's it, You have now created your first level, Sure it not much yet, but you now have an idea on how the very basic UnRealED works. Check out my next Tutorial named "The Basics Phase Two" for more.


Basic Construction 2

Basic Construction Phase Two

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    Well, after making my first tutorial last night, I guess that I had best make this one tonight...

    Abstract:

    This tutorial will pick up where Phase One left off. I will go into joining rooms and some more detail about the general makeup of UnReal Levels...

    Assumptions:

    I make but one assumption here, that you have read and understood Phase One - as this continues where that left off. Apart from that if you have trouble with any of the terms; you should look up my Jargon Tutorial. Things in the jargon tutorial will be marked with *.

    Introduction:

    Now that you have a basic room and a player start, you will want to make more rooms and the like for it (otherwise, lets face it it will be pretty boring...

    Adding another room:

    To create another room is just as easy as making the first. Once again, right click the "cube" button and select the height, width and depth of the cube you want to create, but this time place it just off to the side of the first room that you created, say about half the size of the room away... If haven't moved a brush* (the red wire frame of the cube) yet, it is simply done by holding down control and moving the mouse in one of the 2D views (on this note, make sure that the brush is selected, by clicking on it - if it's not already highlighted). When you are placing the second room, make sure that the floors are on the same height (The brush will move up and down if you have changed the height of the new cube you created) and then once again hit the "subtract" button. Now that you have a second room, play with the textures - maybe continue the theme of the first or change styles entirely (this can easily look bad though - if the change is too drastic) and place a few lights into the room.

    Joining the two rooms:

    Now that you have the two rooms, you must have a way to get from one to another. There are many different ways that this could be done - teleporters, portals and the like, but let's just use a simple hallway for now... Right click the cube, select properties, and then make it narrow (128x128 {height & Width} perhaps) and make it LONGER then will be needed to join the two rooms - but not long enough to reach the opposite side of either room. And place it between the two rooms. Now press the "deintersect" button (the one just below the subtract" button) and you should find that the hallway has been cut off where it meets the room walls. This will make sure that the hallway lines up with the walls and does not overlap anywhere (you can actually cut out something if it is bigger i.e. overlaps, but it slows down the game, rebuilding time, and is bad designing - lets not get into bad habits straight away eh? ). Change the textures if you need to and do the lights. Now I personally like dark hallways as they look great with just a little light spilling over from the rooms on either end - it adds to the whole atmosphere of the game, but if you want to add lights to it, the please do so...

    Adding the light:

    Now you are ready to rebuild again, and do so (if you don't you won't be able to play properly...)

    Saving and playing the level:

    Okay, now you should have a small hallway with two rooms on either end. Still not the !!BEST!! multiplayer map, but I will only teach you how to USE the tools in UnRealED, not create levels (sure that comes into it, But I won't go into floor layouts and the like - unless it is a general piece of advise...). Creating levels is up to you, You now have a basic idea of how UnrealEd works and to go into more depth (only after you have played for a while).


Wolf's Basic Tutorial- A Beginners Guide to UnrealEd

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Introduction

This is a beginners tutorial. If you are experienced with UnrealEd you will probably be bored with this tutorial, but go ahead and read it anyway. Who knows, you may learn something!
The purpose of this tutorial is to show you the basics of getting started with UnrealEd. In it you learn to make basic rooms and add detail to them, how to do basic lighting, texturing, add actors, etc...We will build a small level while familiarizing yourself with the UnrealEd interface.
This tutorial should be enough to get you started. Subsequent tutorials will go into more detail on certain aspects of using UnrealEd.

Getting Started

First of all, to get the most out of Unreal, make sure you have the latest patch (currently 225f) available at Unreal.com.
Second, if you have any problems starting the editor then get the latest UnrealEd fix here.
Third, To get the best performance out of the editor, limit what you have running in the background. Remove everything unnecessary including the screensaver to get maximum performance from Unreal and the editor. UnrealEd is a memory hog.
Tip: If you have been running a lot of games or other CPU resource sensitive applications, then reboot your system. This will help clear virtual memory and RAM and will allow maximum performance from UnrealEd. The more memory you have free, the less chance of a "random crash."
Last, If you have been a Quake/Quake2 editor and are trying out UnrealEd then it might be helpful to read this article: Making the Change.

The Interface

Okay, you got the latest patch, you have the UnrealEd fix and you can run the editor now. This is what you should see:

If the 2D view windows are black then reset all camera views from the menu bar at the top of the editor. This should fix things up nicely. In this (and all of my other) tutorials, I will refer to the icons and other parts of UnrealEd by the names in the Tool Bar Reference. Familiarize yourself with this interface.
You can customize the look of your editor by changing the position of certain windows, etc... but I will always assume they are in the default position when referring to a location.

After you have completed the basic tutorials, feel free to customize UnrealEd as you see fit, but for this tutorial it will be much easier to follow along if you are using the default positions.

Take some time to study the interface. Check out the Browser and right-click the Tool Bar Icons to get familiar with their names.

Features

UnrealEd combines several tools into one all-purpose game editor. It has a Level Designer, Script Compiler, Texture Browser, Texture Making, Package viewer/maker, and Mesh viewer all rolled into one.
Needless to say it's a very powerful tool. We will be mostly using the Tool Bar, and Browser, and of course the 4 map view windows. Know where these are.
Tips: As I tell you "the long way" to do something, I will also mention the "short cut." It's a good idea to refer to the keyboard command and short cuts as we go along.
Click here for the Keyboard Shortcuts.

Menu Bar

Most functions can be accessed via the Menu Bar. It should be evident what they do, but if you are uncertain, again, try it out on a test brush, or test map. You can also use the Tool Bar chart for a reference since the commands are labeled the same in both the Menu Bar and the Tool Bar

Tool Bar

The Tool Bar will probably the menu you use the most. It contains all the icons you need to start editing with UnrealEd. Click the picture for a detailed reference to each button and it's function.

Browser

The Browser has four modes:
Textures
Classes
Music
SoundFX

At the bottom of the Browser is a set of buttons that change with each Mode. They should be self explanatory, but I will refer to them as necessary. There is a lot more on the Texture Browser later on in this tutorial.

This is the Browser in all four modes Mode:

The Four View Windows

This is the where you will spend most of your time. There are different modes for all views that will be explained in each section.

 Basic Terminology

Object - Everything we add to our map is an object.
Brush - A brush is a geometric shape, the basic building blocks or your level.
Active Brush -Also called the Red Brush or Building Brush, this is the red brush you use to add brushes to your map.
Actor - An actor is any non-brush object you add to your map. PlayerStarts, monsters, lights, inventory items, weapons, triggers, etc... are all actors.
Icon - An image used to represent an item. If you use a graphical interface (Windows,etc...) then you should know what an icon is.

 Window Size

You can resize the view ports by clicking the bars between them and moving their position. Be careful with this, because you can crash the editor if you resize the windows with any other windows open (like the 2D Shape Editor, or Floor Lofter).

 Colors
All the brushes in UnrealEd are color-coded for your convenience, making it easy to tell from any view what type of brush it is. Selecting a brush will highlight it a brighter shade of the same basic color.

2D Views

Top View - Overhead
X-Z View - Front View
X-Y View - Side View
This is a 2D view without the menu bar. To open the Menu bar press the green arrow.

This is the 2D view with the menu bar open.

The 2D Menu
The menus you will use most are shown below. For a description of each menu click on its picture.

 2D View Movement
To move your view around in the 2D windows hold the left mouse button and move the mouse around. This will move your view up, down, left and right. Holding both mouse buttons and moving the mouse will zoom your view in and out.

3D View

This is 3D view. The green arrow in the upper left corner (under the menu bar) will open and close the menu bar, just like in the 2D views. The joystick icon next to that will update the 3D view in real-time*. When this is selected, ambient sounds are played, dynamic lights are displayed, textures are animated, and invisible brushes will be shown.

* You can also set each window to real-time updating by clicking in any window and pressing the "P" key. This works in both the 2D and 3D views.

There are five Modes you can select from the menu bar in the 3D Window. These are: Dynamic Lighting, Textures (full bright), Polygon View, Zone/Portal and BSP Cut Views.
Each is shown below with a brief description of each.
The Dynamic Lighting Mode will show lighting as you will see it in the game.

The Texture Mode will show you all the textures unlit (full bright) and not show any lighting effects. A nice feature if you are aligning or changing textures in areas you have already lighted and rebuilt.

The polygon (or poly for short) view will show all your brushes as colored geometric shapes.

This view will show all your zones as different colors. This will help determine if you have an area zoned (or sealed) correctly. Great for finding problems with zones.

The BSP view will show you how the engine "cuts up" the polygons for rendering. If you run into a BSP error (or hole, or HOM)* you can usually find the source with this view. It also helps you determine the speed of a particular area. the fewer the cuts, the faster the rendering.

* BSP errors, also called BSP holes, and HOM effects (short for Hall of Mirrors). They are usually caused by BSP cuts, especially several small cuts into one polygon. This is a common problem with 3D level design. They are almost impossible to eliminate entirely (most of the Epic maps that came with the game have them), but you can usually fix most of them. Big ones must be fixed, but the smaller ones will only appear in certain areas when you view polys at certain angles.

Map Perspective view

This view is a 3D view but the brushes are all wire-frame rendered instead of solid, or textures.

 3D View Movement
Holding the left button and moving the mouse left and right will pan your view in that direction. Holding the right button and moving will roll your view up, down, left and right. Holding both buttons will slide your view up, down, left and right.

The Grid

Always use grid snapping. This will help align your brushes and prevent BSP errors. The default is 16 units and is usually sufficient. You can resize the grid scaling by right-clicking in any 2D window and selecting Grid. You can select a smaller grid setting (such as 8 or even 4) for adding smaller, detail brushes.

Brushes are "snapped" to the grid using the pivot point, shown in the editor as a red cross on a particular point. The default location is the center point. You can change this point by left-clicking to highlighting the brush and then right clicking on the point you want to make the pivot point.>

Putting This to Work

Imagine that the "void" in the 3D view is a large piece of clay. You will make rooms/areas by carving out of this clay the basic shape, and then adding details inside the space created. You will start by subtracting a cube from the world and then adding stuff inside it to make your room. Your primary tool is the active, or red building brush. I will call this "the red brush" or the "building brush." I might also revert to saying things like "reset your brush" and unless otherwise noted this will ALWAYS means your red brush.
Below is the Red Brush in the 3D view.

Your First Room

Adding, Subtracting and Texturing Brushes

Okay, lets make something! Your first room couldn't be easier. First let's see that Red Brush I mentioned. Simply left-click the Cube Tool. You should now see a red cube appear in all 4 views. As explained above, you can turn on the real-time updating now so you can see your movements in all windows. Remember, you can press the joystick icon by the green arrow, or click in a window and press the "P" key to do this.
Note: Any brush visible in the 3D view (except the red brush) will not show movement or even deletion until you rebuild.

Okay, we set the real-time updating in all windows and we still have this red cube. Wow, you say. In the Browser, select the Texture mode. Now we need to load a texture set. At the bottom press the Load button. A windows interface now opens and lists various files with UTX extensions. these are your texture packages. Each one is a set of textures. For now just load Ancient.utx. you can browse through the others later.
A bunch of new textures should now appear in the browser window. These are the textures in the file we just loaded. If you notice under the browser mode there are two pull-down menus. Both currently say all. The first one is to chose a loaded texture set. If you press the down arrow on the right you will see a list of loaded textures. Most are default engine sets, except Ancient, which we just loaded. Make sure Ancient is selected now.
You can press the [image] buttons to move through the loaded sets.
These buttons [image] will set the size (and the number of textures in the Browser window).
The next pull down menu is for the subdivisions within the texture set. This is just a way of grouping the textures in a set by type.

You can press the down arrow on he right of the set and see all the divisions. They should be pretty self-explanatory. For now, select All. You can do this by pressing this button [image] or by the pull-down menu.
Pick a texture by left-clicking it in the browser window. It should now be highlighted with a green border (like the one to the left).
This is the currently selected texture and will be used until you change it.

Having selected a texture, now press the Subtract button and you should now have a cube with the texture you selected. To change any texture left-click it in the 3D window. This will highlight it. Now if you select another texture it will replace the current one. Try changing the floor texture. Okay, we have a basic cube but it's not a level yet. First, we need to add light to it. But before we do that let's Rebuild.

Rebuilding Geometry

Press F8 to open the Rebuild window. This window looks complicated but you don't need to concern yourself with most of it. Rebuilding sets everything up and renders the dynamic lighting for your level. You have to Rebuild to see the results of dynamic lighting on the textures and to see the results after deleting a brush. When you first add rooms they are rendered unlit (full bright) and lighting won't affect them until you rebuild. For more info on the Rebuilder click the image.

Press Rebuild Geometry now to rebuild the level. Just use the default settings and everything is automatic. It only takes a few seconds. Wow...everything went dark in the 3D view! That's because we have no lights.
First, to see where you are in the 3D window, press Mode to get a drop down menu. Now select Texture. This will show you the Texture mode, and not use lighting. Right-click the center of the ceiling in our room and select Add Light Here.
Note: The "Add Light" feature is always on the menu no matter what you have selected in the Browser.
You should now have a little torch icon in all windows. This is your light. Change the mode back to Dynamic Lighting in the 3D view.
Press F8 and rebuild. Close the Rebuild window. Ah...lighting.
But this light is a little too close to the ceiling. Let's move it down some.

 Selecting and Moving Objects
To move an object in UnrealED left click it any view. This will highlight it as the selected actor. Whenever you select an actor you can right-click to get a pop-up menu. You can access the actors Properties from here (more on that later). To move it down in the 2D views (except, of course the top view) left-click it to highlight it and then hold Shift and the Left Mouse Button. Move the mouse up and down and the actor moves with it. You can use this method in any of the views to move objects. Try moving the light around a little in each view to see how it works. In the 3D view the object moves with your view. So you have to highlight the actor and then move your view and the object moves with it. Now highlight the light, and move it down to the center of the cube.

Tips: If you hold CTRL instead of Shift the object will more the same way, except your view will not move with it.
Always left-click and object to select it. If you have an object selected and then right click another object it will select them both (a potentially hazardous situation if you are moving, deleting or changing an objects properties.
You can see how many objects are selected by right-clicking a selected object to open the pop-up menu and checking the first line. It tells you what kind of actor is selected and how many. See the image below. If multiple actors of different types are selected it will look like the second image.

This is the light actor when it's not highlighted and when it is highlighted. Note the greenish tint when it is highlighted? That is your indicator that it is highlighted. Most every actor will have this greenish tint when it is highlighted.

Adding Actors
We now need to place a starting point for our player in the level(so we can actually play it, or just to check it out in the game). In the Browser menu, select Classes. Look down the menu for Navigation Point. Press the minus sign next to it to expand the classes. You should see several classes, but the one we want is PlayerStart. Click it to highlight it and check at the bottom of the browser. On top the buttons down there, is where the editor tells you what is selected. Make Sure it says "Engine.PlayerStart (scripted)."
Now, right-click in the center of the floor of our cube and select Add PlayerStart Here. You should now have a Joystick looking icon there. This is your player starting point. This is the main method of adding actors to UnrealEd.
Note: Often when selecting classes from the Browser, you will accidentally double-click the class. This will pop open the UnrealScript window, showing the script for that class. Simply click the X on the Script Window to close it.

Rebuild your world. Now we need to save this level. Call it something original like TEST1 or something. Either choose Save Level from the Menu Bar or press CTRL-L. Name and save the level. Now press CTRL-P or choose Play Level from the Menu Bar. The log window will start scrolling and when it's done Unreal will open in your level. Now you should be in a small, ugly little room with a mysterious light source. That's what we just built! Bet we can do better.

There's nothing to do here so quit the game and return to the editor. As you know from the little play-test we did, this was no fun. So let's add some more to this level. First off, it would be nice if the light were actually coming from somewhere. Let's make a Torch! There is a handy little torch flame included with the game. You should still have classes in the browser. Click the plus sign by navigation point to close it, and then expand Light. Find TorchFlame and highlight it, but don't add it yet. First we need something for the torch to sit on. Right-click the red brush to highlight it. From the properties menu select RESET and Reset All Positioning. This is in case we rotated it or anything. The brush should move back to center (if you moved it). Now we need to change its size to something smaller than the room! Right-click the Cube Icon on the Tool Bar and open Cube Properties:

Height width and breath are the three dimensions of the brush and should be self-explanatory. Don't worry about wall thickness as that only applies to hollow brushes and we will only be working with solids for now.
Let's make this brush 64 units tall and make it 128 wide x 128 breadth. Make sure it is touching the floor, and touching one wall like below.

Now click the Add brush to world button and you have a block for the torch to sit on. If your new brush overlaps the PlayerStart icon then move the PlayerStart the same way we moved the light before. Now right-click the top of the new brush near the center and select Add TorchFlame here. A big torch should now appear in your map. Using the 2D windows, center the torch on the block. Also, move the light we added previously closer to the PlayerStart. Rebuild again and you should have something like the image to the left.

Tip: You always start a room by subtracting the main room and then using Add we add details and other objects to the room.

When we added the PlayerStart and the TorchFlame you got your first taste of adding actors to the world. You will use this method to add most all actors to the world. Let's add some decorations to the room to get some practice adding actors. Make sure the Browser is on Classes. Now expand Decoration (press the minus sign). Expanding this will give you a long list of items. These are all in-game decorations. If you have been playing Unreal SP then you will recognize most of them. Keeping with our ancient theme of this map lets add a couple pottery jars to this room. Expand Vase and you should see pottery 0,1 and 2. Add one of each to the floor in front of the TorchFlame holder we built, like this:

Notice in the 2D views that the actual meshes of the decorations are drawn. This gives you a great idea of it's actual in-game position and it's size. Rebuild and test your level. You may have noticed you can shoot these pots and destroy them. In a minute I will show you how to place objects inside these vases so you can get goodies when you shoot them.

Moving and Rotating objects

Okay, when we start this level our player is staring at the wall. That's okay, but it would be better to see something when we start. Lets turn him around so he is looking at the torch when we start. To rotate an object in UnrealEd left-click it in the overhead view to highlight it. See that red arrow coming off the icon? That is the direction it will be facing in the game. Now press the Rotate Icon. Still in the overhead view hold CTRL and press the right mouse. When you move your mouse back and forth you will see the object rotate and the red arrow tells you which direction it is facing. If you hold CTRL and the Left mouse button it will rotate on the Z axis (up and down).
This is the PlayerStart icon's direction arrow. Rotate the PlayerStart around and look in the 2D views to see which way it facing. Now I will show you how to set it back. While it's still highlighted, right-click it and from the menu choose Reset and then Reset rotation. The arrow should be pointing back at the wall again. Okay, rotate the PlayerStart so he is facing the torch flame.

Tip: You can rotate actors without pressing the Rotate Icon. Simply hold CTRL and right-mouse in a 2D view will rotate the object.

Let's reposition the player start a little. Click back on the camera view icon (1st icon in the 1st column). Now click the PlayerStart in the overhead view and hold Shift and left mouse button. Move the PlayerStart back against the wall. Now do the same thing with the pottery decorations and move them. I placed mine beside the torch holder like below. Rebuild and play-test the level.

Adding More Rooms and Changing Textures

Okay, this level is still pretty boring. Lets add some more rooms and stuff to spice it up a bit. First thing to do is make sure nothing is highlighted (click the Select None Icon on the Tool Bar). Now from the Menu Bar under Brush select Reset and Reset All. This will reset our red brush back to the starting position and reset its rotation and scaling. Now lets build a bigger room next to this one. Right-click the Cube icon and let's size this one a bit bigger than the first. Make it 512 x 512 x 512. In the overhead view move the red brush so it is next to (and touching) the first room.

Now press the Subtract button. In the 3D view you should now have a big room next to the first one. Let's retexture this room. Click any wall in the room to highlight the texture.

Highlighted Texture

We are going to retexture the whole room so select all the textures in this room. The fast way to do this is to press Shift-B to select the whole brush. With one wall highlighted press CTRL-B and now the whole room should be highlighted. Now in the Browser change it to Textures. Choose the Ancient Textures, and then choose Wall. Click one of the wall textures in the Browser and now are new room should be re-textured. We don't really want the floor and ceiling the same as the walls, so lets change them. Click on the floor in the 3D view to highlight it. Now if you press CTRL and left-click any other surface it will add that surface to your selection. Remember: hold CTRL while selecting surfaces to select multiple surfaces. So with the floor selected hold CTRL and select the ceiling. Now only the floor and ceiling should be highlighted. In the Browser select the Floor textures the same way we selected Walls. Pick a texture you like and click it to change the floor and ceiling to this texture.

Duplicating Brushes

There are a couple ways to duplicate a brush. For this exercise we are going to learn to Copy a brush, or more exactly, to copy the brush to the red brush and then adding it somewhere else.
Now we need a light source in the new room and to stay with our theme we are going to make another torch holder like the first. Click on the first torch holder we made to highlight it. Now right click and on the pop-up menu choose Copy Polygons, and To Brush. This will move the red brush to the torch holder and make it an exact copy. Now where ever we place the red brush and press add it will make a duplicate of the torch holder. Before you move it, click the Select None Button or simply click in any window so that the brush we copied from is not highlighted. Now in the overhead view, move the red brush into the new room we made. In the X-Z or Y-Z 2D views move the brush down so it is touching the floor. You will notice now that new room floor is much lower than the first room. That is okay, we will make stairs in a few minutes!

Okay, with the red brush positioned where you want the new torch holder press the Add icon. Now move the red brush to the opposite wall and add another. You should end up like this:

Now we need more torches on those holders. You can go to the browser, select Classes, expand Light and then highlight TorchFlame again. Right-click where you want them and add them like we did the first time. Or, you can use this shortcut:
Click the first TorchFlame we added to highlight it. Now press CTRL-W. This will make a duplicate TorchFlame, just slightly off-set from the first. By holding Shift and Left mouse button we can move this TorchFlame to the new location. In the overhead view move the new torchflame over the holder in the new room. In one of the side views (x-z or y-z) move it down to the top of the holder. When the first one is positioned, duplicate it again and move it over the next torch holder. You should now have something like this:

Rebuild and play the level if you wish. I know, There is no way back to the first room! We need to make some stairs to get back to the first room so lets do that.

Stairs

As always, start by resetting the red brush. Now click on the stair Icon in the tool bar. The red brush should now look like a set of stairs. We need to move it to position so hold shift and in the overhead view move it into the new room so it is touching the wall between the two, and center it.

In the side views you will notice the stairs are up in the air. Move them down to the floor of the second room. Check all the views to make sure the stairs are just where you want them. Once they are, simply click add and you have stairs!

Actor Properties

Let's add some more decorations to make sure we know how. In the Browser select Classes and expand Decoration. The first one is a barrel so lets add some barrel is this room. Highlight barrel and right-click in the 3D view where you want the first one and select Add Barrel here. Add two or three of them. Position them against the wall. Now let's learn how to add goodies to them. Left-click on a barrel to highlight it, then right-click to get the pop-up menu and choose barrel Properties. A new dialog window has opened. Take a minute to familiarize yourself with the properties window. Click the image to learn more about the Properties Menu.

All actors will have the same basic Properties window. There are several things we can set here but a lot more that will have no affect on this actor. The sheer number of fields of in the Properties Menu seems daunting. The truth is you only be concerned with a few fields at a time and most you ever touch. Each actor has a specific field with properties significant to that actor and almost everything you will set for that actor will be in that field. Since this actor (the barrel) is a Decoration, we will only concern ourselves with things under Decoration. Expand Decoration. You will see several properties here that are customizable. You should be able to figure out what they do from their names. Since we want to put stuff in the barrel, it makes sense that we would use the field Contents. Okay, let's put something in there. But how? I'll show you.

Go to the Browser. It should still be under Classes, which is what we want. Now collapse decoration by clicking the plus sign next to it and then expand Inventory. We want to put something in there we can pick up. Under Inventory there are two sub-classes: Pickup and Weapon. Weapons should be obvious, and Pickup is everything else we can pick-up, including Ammo. Well, you probably don't want to be running around in Unreal with just the Dispersion Pistol, so lets put a bigger weapon in this barrel. Expand Weapon and you will see all the Unreal Weapons there. Since I like the ASMD and it's the first one, lets place one in the barrel. Highlight ASMD in the Browser. Now in the Barrel properties window go to Contents and click where it says None. You will see some buttons on the right of it now. If you click Use now it should add the ASMD where it used to say None.

Now if you click the ... button it will close the contents field. Close the Barrel Properties now.

A weapon isn't much good without ammo, so collapse the Weapon sub-class and expand Pickup. The first Subclass is Ammo, which is what we are after so expand that. You will see all the Ammo for all the unreal Weapons now. Highlight ASMD AMMO now.

In the Overhead view right-click another barrel, open it's properties, and add the ASMD AMMO the same we way we added the ASMD to the other barrel.
Close the barrel properties. Rebuild, save and then run the level. Now when you shoot the first barrel you'll get the ASMD and the next one will give you some ammo for it. The third one is empty.

Let's add another room but first, a hallway to connect it to the last room. Reset the red brush. Right-click the cube icon and open it's properties. Set its size to 256 x 512 x 256. Position this cube so it's even with the floor of the last room and connected to the first room like this:

Subtract this room. Now, I will show you a short cut to retexture the walls. If you have been following along, then the entire hallway is textured like the floor/ceiling of the last room. If we hold ALT and Right-click the wall texture in the room with the barrels, this will load that texture. Now if we hold Alt and Left-click one of the walls in the hallway it will copy the wall texture we loaded to it. Change the wall texture of both long walls in the hallway. Now resize the red brush to 512 x 512 x 512 again. Move it like we did the hall remembering to raise it in the side view until the floors are even. Now subtract it.

The walls are the right texture but the floor/ceiling is off. So using the method we used to change the walls in the hall, change the floor and ceiling in the new room.

Tip: You can add actors to the level the same way we did decorations. Weapons and pickups don't have to be inside other objects (like barrels). Simply highlight them in the Browser, right click in the 3D window where you want to place them, and Add it there. You can reposition it after it's added if you need to, like we did before.

 Adding Creatures

Okay, this new room is going to be the home of a bad guy we get to fight! Now, we want the element of surprise on our baddie, so lets make a little alcove he will be in so we can get close to him without him seeing us. Resize the red brush to 512 x 256 x 256 and move it against the wall like this:

Subtract it and re-texture it. Now lets add the bad guy. In the Browser, make sure you are in Classes. Expand Pawn and then Scripted Pawn. These are all the creatures in Unreal. We hate the Skaarj so lets add one of those to fight. Expand Skaarj and you will see the two subclasses of Skaarj. Expand SkaarjTrooper. Highlight SkaarjGunner and add one to the alcove. He should be facing the right way but if he is not rotate him so that he is.

Before we go on, we are going to need light in the new room so copy the brush to the Torch holder and add a couple more torches in the new room. I put mine on either side of the alcove like this:

Now rebuild and run the level. Remember to get the ASMD and the ammo from the barrels before disturbing the Skaarj. Now go kill him! :)

Well, chances are, the Skaarj killed you because he has an Eightball. See if you can figure out how to give the SkaarjTrooper an Automag instead! In case you didn't figure it out, do this: In the Browser, under Classes, under weapons, select the AutoMag. Now open The SkaarjGunner Properties and expand SkaarjTrooper. There is only one field here: WeaponType (I think we are on to something here :)). Click where it says Class'UnrealShare.Eightball' and then Clear. If you rebuilt now the Skaarj would have no weapon, but let's since we have AutoMag already selected give him that by clicking Use (just like we did when we added the pickups to the barrel). Now if you rebuild and run the map the skaarj will only have the AutoMag and when you kill him he will drop it and you can pick it up. Cool, huh?

You add all creatures (good and bad) the same way. Each has his own properties you can customize. The creature AI is pretty good in Unreal but that is beyond the parameters of this tutorial. For more info on creatures and getting them to do what you want read Steve Polge's article on the Unreal Tech Page.

Texture Properties and Alignment

Alright, let's play around with textures a little bit. First make another room out of a cube 512 x 512 x 512. Place it on the left side of the alcove where the Skaarj and line it up so the floor is even with the floor of the alcove. Go ahead and subtract it. Lets give this room a new texture. First, go to the Browser, select Texture mode and then load the Skaarj.utx texture set. Pick on e of the Wall textures and texture all the walls in the new room with it. Now from the Floors section select the last one "Xpth" and texture the floor and ceiling with it. Lets add another leg on this room. Press the Cube Icon and make the red brush 256 x 256 x 512 and then press build, then close the window. Align your red brush up with the floor of the last room and make it extend out like a hallway. Retexture the walls and floors just like the last room. Now left-click the hall we just added, and then right-click and Copy Polygons to brush like we did before. Make sure nothing is selected, and move the red brush so that it is at the end of the new hall at 90 degrees, making a "T" shape. Now you should notice that floor and ceiling textures of the last hall don't quite match with the new hall. It doesn't look too bad with this texture, but dammit, I want them to line up.

The easiest way to align textures so that they all match is to align them all as either walls (for vertical surfaces) or floor/ceilings (for horizontal ones). To do this simply right-click the texture and from the pop-up menu choose align, and you will see your choices. You can select multiple textures as always before doing this and align them all at once. You can also do this by right-clicking, and opening the Surface Properties menu (more on that below). Align the floors and ceilings now. Once you have aligned the textures go ahead and add some lights to the parts we added. It's a good idea to make the light come from a light source. Look that Light textures and find one you like. Make brushes sized to match the texture. You can get the texture size by clicking the single texture button; the first one of these: .

Take some time to experiment with the different Surface Properties. There are a lot of settings under Effects you should get familiar with. Try making one of the walls in the new hall a mirror (check mirror under effects). Try a texture that pans (check U-pan or V-pan). Make three lights (each one in the a different room) and texture it with one of the Light textures. Place a light about 32 units in front of each light. Leave one light texture "normal," set one to Unlit and one to Bright Corners. Note the differences of each.

There are lots of things I could walk you through in using the texture properties, but then I wouldn't have anything left to put in the forthcoming Texture Tutorial :)

For now, here are all of the Surface Property menus and a brief description of them.
Most common settings are things like transparency, mirror, unlit (full bright), bright corners, panning, special lit. You can also set the texture panning in the Tool Bar. If you are not sure what each setting does, try it in a test map. Make sure real-time updating is set in the 3D window to view the effect. You must Rebuild to see the changes in the game.

These will rotate and flip the texture as indicated by the buttons. The Small and Big Diagonal will also scale the texture.

This will pan (or move) the texture in the direction of the buttons. The numbers indicate how many units it will move the texture.

This will align the textures in the direction indicated by the button. For example, if you want all your floor or ceiling textures to align highlight them all and select Align As Floor/Ceiling.You can also align by highlighting the texture, right-clicking and using the pop-up menu.

This will scale or resize your textures. One is the standard size, 2 is the two times the standard, etc...

This will show/hide selected objects in the editor. I usually use the buttons on the Tool Bar.

Other Shapes

One more thing to know is that rooms don't have to be cubes. Try making rooms out of Cylinders or Cones. You resize them the same way we did with the cube, by right-clicking the icon and setting the size under it's properties window. Add a couple more rooms out of cylinders, or cubes or Cones, whatever you like. Take some time to experiment and play around with the different shapes.

In Conclusion

This concludes the Basic tutorial. You should be able to build rooms, texture them, add lights, add actors etc... just enough to get you started. Play around and get familiar with interface and then move on to the advanced tutorials.

Note: There are several things we just "glossed over" in this tutorial. This tutorial is just to get you familiar with UnrealEd and to learn the very basics of level design. Subsequent tutorials will go more in depth on specific functions and tools of the editor.

TIPS

Start small. Hold on to that grand idea and make little test maps to try and work out something you are trying for the first time. Once you have it working right, save your map to refer to if you get stuck.

Forget vertex manipulation in UnrealEd. It is buggy at best and I almost never use it.

Always remember to subtract an area and then add stuff to it.

ZONES! A lot of things that were just brushes in Quake are zones in UnrealEd (such as water/slime/and Lava).

Remember there are a lot of useless properties in the properties window of the actors. most things you can change in a certain actors properties are in that actors specific fields. Such as Light for Lights, Decoration for decorations, Inventory for pick-ups, etc... Look for the actor specific fields when trying to customize actors.

Good luck, have fun and as always, if you need further help, let me know.

-Wolf

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


How to build a basic map.

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

This tutorial is the first in a short series on how to use some of the new features in the UnrealEd 2 Editor.

Most of the things you can do with the editor are exactly the same as the ones you can do with the old editor and most of the old tutorials will work just as well, once you know your way around. I do not intend to cover advanced topics in here so if you are at that stage then I hope you are also at the stage where you can use the other tutorials. If you still find anything to hard to understand then you can always email me.

\-Blacksway-\
Make your first room

We will start by making a 512x512x512 room.

Cube Builder Icon Right click on the cube builder icon to the left. Enter 512 in each of the first three boxes for height, width and breadth.

The number 512 is chosen because Unreal works best with powers of 2. 1 foot is about 16 units and therefore 512 makes a large 32x32x32 foot room. You can also enter simple equations in for the values here, for example '=512*4' and then press enter and it will change to '2048'. Cool hey!

Click on the Build and the building brush will now take on the shape of this cube. The building brush is the red wireframe brush in each window. Then you can click on close to get rid of the cube builder options. To recreate the same shape at any time you can left click on the cube builder icon again.

Subtract Icon Now you need to subtract the building brush from the world (as in Unreal the whole world is like a lump of clay and you start by carving bits out of it) by pressing on the Subtract icon to the left.

The lower 3d view should now have a cube appear in it. Holding down the right mouse button and moving the mouse will allow you to swivel the view around. Do this until you can see the floor of you room.
Add a Starting Point

Actor Browser Icon Bring up the actor browser window by clicking on the Chess piece on the toolbar at the top. Navigate down from Actor to NavigationPoint and then click on the little plus symbol next to NavigationPoint. Now move down to PlayerStart and select it by left-clicking on it once.

Now right click with the mouse on the floor of your room in the 3D view and a popup menu appears. Choose Add PlayerStart from near the top and a little joystick should appear in all the views.
Moving Around and adding Light

Next you will need to move your view so you can see the ceiling of the room. If you hold down the left and right mouse buttons together your view will move up and down the z-axis (height). If you move your view downwards and the holding down the right mouse button as above swivel your view so you can see the ceiling of your room.

Now right click on the roof of your room and choose Add Light from the popup menu. Add Light is always on the popup menu and doesn't have to be found in the Actor browser.
Play Your Level

Build All Icon The first step to playing your level is always to BUILD. Click on the Build All icon (a cube and a light bulb together) on the toolbar at the top and you will see the room textures change. This icon builds geometry (and BSP), does the lights and defines your paths. These 3 stages can be done seperately using the 3 icons to the left of the build all icon.

If you ever move or change any brushes (not actors though) you must always do at least the first step before playing your level else you will always die whenever you enter the level.

Play Level Icon You have now created your first room. If you clicked on the Joystick icon at the top to play the level then you would have finished. Warning! I should tell you that if you did do that and you are using UnrealTournament then you would probably die lots as the game usually starts with lots of bots. These bots would all try to appear on your one PlayerStart end kill each other and you. It may therefore be best to backtrack and add another 6 or 7 PlayerStarts around your floor just to make things safe. Alternatively follow the steps outlined inthe notes below.

You have now created your first map. If you need anymore help then check out my links page for tutorial sites and if you're still stuck then email me. Also check out part 2 HERE.

\-Blacksway-\
Notes

1. Always remember to Rebuild!

2. To avoid the situation above where lots of bots are spawning ontop of you go into UT normally, start a practise match with 0 bots and then exit. Next time you test your level you will be the only person playing. Type AddBots at the console to manually add them.


How to build a basic map

How to build a basic map - Part 2.

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

This tutorial is the second in a short series on how to use some of the new features in the UnrealEd 2 Editor.

Most of the things you can do with the editor are exactly the same as the ones you can do with the old editor and most of the old tutorials will work just as well, once you know your way around. I do not intend to cover advanced topics in here so if you are at that stage then I hope you are also at the stage where you can use the other tutorials. If you still find anything to hard to understand then you can always email me.

\-Blacksway-\
Our first room was a bit crap!
Well we started by making a 512x512x512 room. It had this wonderful bubbly texture all over it didn't it, looked a bit crap. Also it was too tall. Well first, lets change the textures..
Lets make it look prettier

Texture Browser The first step is to bring up the texture browser, by pressing the icon to the left (looks like a little landscape painting doesn't it!).

Docking Button Next we are going to dock the texture browser and the actor browser into the master browser. To do this click on the left most icon on the texture pop-up window, shown on the left. Bring up the Actor browser (by pressing the chess piece icon) and do the same for this. Then the 2 browsers will be contained in one window and you can change between the 2 by pressing the relevant tab at the top.

Return to the texture browser. Choose File->Open or click on the open icon and choose a package to load. A package contains a set of texture, which can themselves be seperated into groups. Choose City.utx for the package to open.

In the 3D view window left click once on the floor of your room. It should so that a blue dot-pattern appears on it. Now click on the second texture in the texture window, ALLEY2. You should see the floor change texture.
What about the wall!
Next you want to select all the walls of your little box. Now you could click on them one at a time and then holding down the CTRL button click on the rest, but this would involve lots of moving around to view all 4 walls. A far easier way is to right click on any wall and from the pop-up menu choose Select Surface->Adjacent Walls. All 4 walls in your room are now highlighted. Click on the BRICKWAL texture to texture your walls. You can now rotate the view to show the ceiling and place a texture on it too.
But my room is too high!

Close the texture browser by clicking on the little cross so that you can see all 4 view windows.

The view we are interested in at the moment is the Front view in the top right hand corner.

Holding down the left mouse button and moving the mouse to center your room in the middle of the window and then hold down both mouse buttons to zoom in so that the room covers most of the window.

You may notice that the red builder brush is showing on top of our room. to hide the builder brush you can press B. THen select the brush that is your room so it turns a light brown color.

Then we are going to change into Vertex Editing mode by clicking on the icon to the left. Now to select all the vertexes that make up the 'roof' of your room hold down the CTRL and ALT keys drag a box around the top of your box, making sure to cover both corners shown in the image below.

The 2 corners should now be hightlighted in white (it is actually all 4 vertexes, but you can't see the back 2).

Holding down the CTRL key and the left mouse button you can now move these points down to make the roof lower.
Cor Blimey, anything else!
Well you may have noticed that now the little torch is actually above the roof of your room. So change back to normal mode by clicking on the camera icon and left click on the torch. Now hold on to the CTRL key and press the left mouse button to move it down, back below the roof of your room.
Lastly
REBUILD! If I've had to say this once I've said it lots of times to people who email me, rebuild, rebuild, rebuild! Now you've done that you can play your newly texture level and away you go.

If you need anymore help then check out my links page for tutorial sites and if you're still stuck then email me

\-Blacksway-\


How do I select a brush

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

To select a brush click on it with the left mouse button.

If no brush is selected then the following actions will be applied to the builder brush by default
How do I move or rotate the brush

Holding the Ctrl and Left-Mouse button will move the brush around the map.

Holding the Shft and Left-Mouse button will move the background, keeping the brush in the center of the screen.

Holding the Ctrl and Right-Mouse button will rotate the brush around its pivot point.
How do I move around the view?

Check out the View Basics section...
How do I use the new Drag-Select function

The function is used by holding down the Ctrl+Alt keys, then left clicking and dragging a box around one or more actors. It is best if you release the mouse button before releasing the keys, as sometimes it might leave the box on screen if you do it the other way around

The actors which are selected are defined by those whose pivot points are contained within the drag-box.


Mapping Key Commands

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Below is a list of commands which can be mapped to keys. Simply edit the USER.INI file and assign them to a key.

As of UnrealEd 2 you can also assgin them to user-defined buttons by adding the following to UNREALED.INI as follows:

[UserDefinedGroup]
NumButtons=1
Button0=Camera Move Mode,ModeCamera,MODE CAMERAMOVE

Each button has 3 parts, 1: Tooltip text, 2: Image filename, must be 30x30 BMP and in EditorRes directory, 3: Command

Changing Modes
MODE BRUSHCLIP | Change to brush clipping mode
MODE BRUSHROTATE | Changes to brush rotate mode
MODE BRUSHSCALE | Changes to brush scaling mode
MODE BRUSHSHEER | Changes to brush sheer mode
MODE BRUSHSNAP | Changes to brush snap mode
MODE BRUSHSTRETCH | Changes to brush stretching mode
MODE CAMERAMOVE | Changes to camera moving mode
MODE CAMERAZOOM | Changes to camera zoom mode
MODE GRID=[1,0] | Turns grid on or off (1 = On, 0 = Off)
MODE FACEDRAG | Changes to the new Face Drag mode. What you have to do is select a brush and then enter this mode. Then press CTRL+Left Mouse to one side of the brush and you can move that face.
MODE MAPEXT=[1,0]
MODE ROTGRID=[1,0] | Turns rotational grid on or off (1 = On, 0 = Off)
MODE SHOWVERTICES=[1,0] | Turns vertices on or off (1 = On, 0 = Off)
MODE SNAPDIST=x | Distance of vertex to grid intersection before snapping to it
MODE SNAPVERTEX=[1,0] | Turns vertex snap on or off (1 = On, 0 = Off)
MODE SPEED=[1,2,3] | Changes movement speed 1,2, or 3
MODE TEXTURELOCK=[1,0] | Turns texture lock on or off (1 = On, 0 = Off) - If texture lock is on then textures will not be reset on brushes that are vetex manipulated
MODE TEXTUREPAN | Changes to texture pan mode
MODE TEXTUREROTATE | Changes to texture rotate mode
MODE TEXTURESCALE | Changes to texture scaling mode
MODE VERTEXEDIT | Change to vertex editing mode

Actor and Brush Commands
ACTOR ADD CLASS= | add actor of class (ie: CLASS=ASMD)
ACTOR APPLYTRANSFORM | applies the transform permanently to selected brushes
ACTOR CLIP Z | In wireframe view it culls brushes that are after a certain distance. The distance being determined by where the Active brush is when it's pressed. Press again to disable. Useful for complex maps.
ACTOR DELETE | deletes currently selected actor
ACTOR DUPLICATE | duplicates currently selected actor
ACTOR HIDE SELECTED | hides the currently selected actors / brushes
ACTOR HIDE UNSELECTED | hides any actors / brushes that are not currently selected
ACTOR KEYFRAME NUM=# | set the current actor to key frame number #
ACTOR MIRROR [X,Y,Z] | mirrors the selected actor about the X, Y or Z axis
ACTOR REPLACE BRUSH | replace selected brush with the builder brush (ie. If you select an added brush and issue this command it will be replaced with another added brush that is the shape of the current builder brush, same for all other brush types)
ACTOR REPLACE CLASS | replace selected actor with actor of class type (ie: CLASS=ASMD)
ACTOR RESET ALL | resets the selected brush (Location, Pivot,Rotation and Scale
ACTOR RESET LOCATION | resets the selected brush's Location
ACTOR RESET PIVOT | resets the selected brush's Pivot
ACTOR RESET ROTATION | resets the selected brush's Rotation
ACTOR RESET SCALE | resets the selected brush's Scale
ACTOR SELECT ALL | selects all brushes / actors within the map
ACTOR SELECT DELETED ???
ACTOR SELECT INSIDE | selects all brushes / actors within the builder brush
ACTOR SELECT INVERT | inverts the state of selected to unselected and vice versa
ACTOR SELECT NONE | deselect the selected actors
ACTOR SELECT OFCLASS CLASS= | selects all actors of class type
ACTOR SELECT OFSUBCLASS CLASS= | selects all actors of subclass type
ACTOR UNHIDE ALL | shows all actors / brushes that may have been hidden
BRUSH ADD | creates an additive brush
BRUSH ADDMOVER | creates a mover brush
BRUSH APPLYTRANSFORM | transform the selected brush permanetly
BRUSH FROM DEINTERSECTION | creates new brush from the deintersection operation
BRUSH FROM INTERSECTION | creates new brush from the intersection operation
BRUSH MORE ???
BRUSH SET ???
BRUSH SUBTRACT | creates a subtractive brush
BRUSHCLIP | performs the clipping operation on the selected brush
BRUSHCLIP DELETE | deletes the clip markers used to perform brush clipping operation
BRUSHCLIP FLIP | flips selection arrow denoting what side of brush to clip
BRUSHCLIP SPLIT | splits the selected brush along the clipping plane
Texture Commands
POLY DEFAULT TEXTURE= | sets the default texture in the texture browser
POLY SELECT ADJACENT ALL | selects all adjacent polys
POLY SELECT ADJACENT CEILINGS | selects all adjacent ceiling polys
POLY SELECT ADJACENT COPLANARS | selects all adjacent coplaner polys
POLY SELECT ADJACENT FLOORS | selects all adjacent floor polys
POLY SELECT ADJACENT SLANTS | selects all adjacent polys on the same slant
POLY SELECT ADJACENT WALLS | selects all adjacent wall polys
POLY SELECT ALL | selects all polys in the map
POLY SELECT MATCHING TEXTURE | selects all matching surfaces that share the same applied texture
POLY SELECT MEMORY | selects any polys that have been remembered in memory
POLY SELECT NONE | deselect any currently selected poly
POLY SELECT REVERSE | inverts the state of selected to unselected and vice versa
POLY SELECT ZONE | selects all polys in the current zone
POLY SET TEXTURE= | sets the poly to the given texture
POLY SETTEXTURE | sets the poly to the current selected texture
POLY TEXALIGN FLOOR | aligns the textures to the floor plane
POLY TEXALIGN ONETILE | aligns textures to one tile fitting
POLY TEXALIGN WALLCOLUMN | aligns texture to Wallcolumn
POLY TEXALIGN WALLDIR | aligns the textures to the wall plane
POLY TEXALIGN WALLPAN | pans out the textures on the wall plane
POLY TEXINFO | displays information about the texture like scaling multipliers
POLY TEXMULT UU=# VV=# UV=# VU=# | multiplies the scaling of the current texture from whatever it is now, UU and VV normal, UV and VU are skewing directions.
POLY TEXPAN U=# V=# | pans textures along the U and V axis by the supplied number of units
POLY TEXSCALE UU= # VV= # UV= # VU= # | Scales the texture by numbers entered for U and V and skews the texture for numbers entered for UV and VU. This is an absolute scaling, whereas TEXMULT is a relative one.
TEXTURE APPLYDETAIL | Apply the "current detail texture" to the texture selected in the texture browser
TEXTURE BATCHAPPLY DETAIL=[DetailTextureName | None] [PREFIX=TextureNameMatchingPrefix] [OVERRIDE=[TRUE | FALSE]] | Search through all texture packages optionally searching for matches against the "TextureNameMatchingPrefix" for all textures found, apply DetailTextureName as the new detail texture. If a detail texture already exists and OVERRIDE=FALSE, then skip the texture
TEXTURE CLEAR | For Fire textures, clears any 'blotches' (I don't know how to describe this any better, sorry!)
TEXTURE CLEARDETAIL | Clear the current detail texture
TEXTURE CULL | Remove Textures references on all Non Visible Surfaces
TEXTURE REPLACEDETAIL | Search through all texture packages for occurrences of detail textures that match the texture currently selected in the texture browser. If a match is found, replace the texture's detail texture with the "current detail texture.
TEXTURE SCALE DELTA=# ???
TEXTURE SETDETAIL | Set the "current detail texture" to the current the texture browser selection
Miscellaneous
BSP REBUILD [LAME/GOOD/OPTIMAL] [BALANCE=0-100] [LIGHTS] [MAPS] [REJECT] | rebuild BSP with default settings or custom settings in brackets
CAMERA ALIGN | aligns all cameras on the currently selected actors/ brushes
CAMERA CLOSE FREE | closes all free viewports or FREE can be substituded for the name of a specific viewport
CAMERA HIDESTANDARD | hides all standard viewports
CAMERA OPEN | opens a new viewport
CAMERA UPDATE | updates viewport
CLASS LOAD FILE= | load class from file
CLASS NEW | create new class
CLASS SPEW ALL | exports all scripts to your UT folder, folders are created for each class. ALL can replaced with specific class (ie BOTPACK)
DELETE | deletes selected actors / brushes
DUPLICATE | duplicates selected actors / brushes
EDCALLBACK SURFPROPS | bring up the surface properties of selected poly
EDIT COPY | copies selected actors / brushes
EDIT CUT | cuts selected actors / brushes
EDIT PASTE | pastes selected actors / brushes
JUMPTO X,Y,Z | puts all viewports centered on entered coordinates
LEVEL LINKS | update teleporter links
LEVEL REDRAW | redraws the level views updating any changes
LEVEL VALIDATE | validate the level, find errors
LIGHT APPLY | applies lights in your level
LSTATS | displays lighting stats
MAP [LOAD/SAVE/IMPORT/EXPORT] FILE= | executes the load, save and import commands with the given filename
MAP BRUSH GET | copy selected brush to builder brush
MAP BRUSH PUT | move selected brush to builder brush location and take on shape of builder brush
MAP NEW | start new map
MAP REBUILD | rebuild map (geometry/bsp)
MAP SELECT ADDS | selects all additive brushes in the map
MAP SELECT FIRST | select the first created brush in the level
MAP SELECT LAST | select the last created brush in the level
MAP SELECT NONSOLIDS | selects all nonsolid brushes in the map
MAP SELECT SEMISOLIDS | selects all semisolid brushes in the map
MAP SELECT SUBTRACTS | selects all subtractive brushes in the map
MAP SENDTO FIRST | send selected brush to the beginning of the bulding process
MAP SENDTO LAST | send selected brush to the end of the building process
PATHS BUILD | auto create pathnode network - opt=1
PATHS BUILD HIGHOPT | auto create pathnode network - opt=2
PATHS BUILD LOWOPT | auto create pathnode network - opt=0
PATHS DEFINE | create reachspecs
PATHS HIDE | hide pathnodes
PATHS REMOVE | remove all pathnodes
PATHS SHOW | show pathnodes
PATHS UNDEFINE | remove all reachspecs
PIVOT HERE | places a pivot a the previously selected grid point
PIVOT SNAPPED | snaps pivot to grid
SCRIPT MAKE | compile scripts
SELECT NONE | deselect any selected actor
SETCURRENTCLASS CLASS=<ClassName> | set the current class to <ClassName>
SHOWINV | toggle the showing of inventory spots
TRANSACTION REDO | redo previous action
TRANSACTION UNDO | undo previous action


BB Drac - Unreal Tournament UED2 guide Rooms

A Single Room

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

When you start UED2 you get a screen that is divided into four work areas.
Each is a different view.
The bottom left is the 3D view, top left is from above. The two right windows is
from the front and the side.

The entire world is at this point filled with mass.
(More info on this subject and what each button do is explained in other
sections of this UED2 guide.)

To create a simple DM level we need some space for our players to run around inside.
So lets start with the first room.

To do this we need to create a builder tool first.
Click the right mouse button on the "cube builder" button. Screenshot

A window "cube builder" properties will come up and let you adjust the size and parameters
of the builder.
Enter height 256, width 512 and breadth 512 (as shown on picture below).
Screenshot

When this is done press the "build" button and a large red square should appear in all
windows, right? Something like this...

(Press the close button to close the builder properties window.)

We have not yet created a room in this world.
The red cube is only a builder tool. It may be shapes in any way, it still
does not affect the level itself.
(See info about builders for more details).

Now, lets create this room. To do so we need a texture to add to the walls.
To bring up the texture window either select "view" and "texture browser..." or press
this button. Screenshot
A new window comes up with some textures showing. We want to load others.
Select "file" and "Open..."
Load the "ancient.utx" file and some new textures will show in the texture browser.
Right now it is showing the "Arch" group. Select "Floor" and then click the texture
named "FLOOR1".

When "FLOOR1" is selected you may close the texture browser window. The texture will still be
selected if you wondered.

Now comes the creating itself. Press the "subtract" button Screenshot to remove mass equal to the builder
cube we created.
Afterwards you will see that a room (equal in size as the builder cube) with our selected
texture has been created.

Screenshot

Now we want to change the texture on the walls. To do so, bring up the texture browser
again and select the "Deco" group and click the texture named "A_hd".

Close the texture browser again.

Press the right mouse button on one of the walls and select "applay texture".
Repeat this for all the four walls.
(To move about in the 3D view you hold one or both of the mouse buttons.
The left to move horizontal and the right to change direction in 360 degree angel.
Both mouse buttons to move vertical.)

Screenshot

We also want to change to roof texture.
Open the texture browser and select group "Deco" and texture "DCRL".

Close the browser.
Apply the texture to the roof with the same procedure as above.

Screenshot

Now we have created a simple room. Now we need some light.
Press the right mouse button somewhere in the room and select "Add Light Here".

To actually play the level we need a player starting point.

Open the "Actor class browser" window by either selecting "View" and "Actor class browser..."
or pressing the "actor class browser" button. Screenshot
Expand the "NavigationPoint" and select "PlayerStart".

Place this somewhere by pressing the right mouse button on the floor and select "Add PlayerStart here".
A joystick should appear.

When all this is done only one thing remain.
That is to "build" the level. Select "build" from the menu and select "build options..."
Do nothing and press the build button.

When the progress bar is gone press the hide button.

Save the level and try it in UT.


BB Drac - Unreal Tournament UED2 guide Tutorial DM part 1

The first room

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

NOTE:
To follow this guide no knowledge of UED2 or 3D creation is needed.
Understanding the basics of UED2 (builder buttons and like) is preferred.

When you start UED2 you get a screen that is divided into four work areas.
Each is a different view.
The bottom left is the 3D view, top left is from above. The two right windows is
from the front and the side.

The entire world is at this point filled with mass.
(More info on this subject and what each button do is explained in other
sections of this UED2 guide.)

To create a simple DM level we need some space for our players to run around inside.
So lets start with the first room.

To do this we need to create a builder tool first.
Click the right mouse button on the "cube builder" button. Screenshot

A window "cube builder" properties will come up and let you adjust the size and parameters
of the builder.
Enter height 256, width 512 and breadth 512 (as shown on picture below).

Screenshot

When this is done press the "build" button and a large red square should appear in all
windows, right? Someting like this...

(Press the close button to close the builder properties window.)

We have not yet created a room in this world.
The red cube is only a builder tool. It may be shapes in any way, it still
does not affect the level itself.
(See info about builders for more details).

Now, lets create this room. To do so we need a texture to add to the walls.
To bring up the texture window either select "view" and "texture browser..." or press

this button. Screenshot
A new window comes up with some textures showing. We want to load others.
Select "file" and "Open..."
Load the "ancient.utx" file and some new textures will show in the texture browser.
Right now it is showing the "Arch" group. Select "Floor" and then click the texture
named "FLOOR1".

When "FLOOR1" is selected you may close the texture browser window. The texture will still be
selected if you wondered.

Now comes the creating itself. Press the "subtract" button Screenshot to remove mass equal to the builder
cube we created.
Afterwards you will see that a room (equal in size as the builder cube) with our selected
texture has been created.

Screenshot

Now we want to change the texture on the walls. To do so, bring up the texture browser
again and select the "Deco" group and click the texture named "A_hd".

Close the texture browser again.

Press the right mouse button on one of the walls and select "applay texture".
Repeat this for all the four walls.
(To move about in the 3D view you hold one or both of the mouse buttons.
The left to move horizontal and the right to change direction in 360 degree angel.
Both mouse buttons to move vertical.)

Screenshot

We also want to change to roof texture.
Open the texture browser and select group "Deco" and texture "DCRL".

Close the browser.
Apply the texture to the roof with the same procedure as above.

Screenshot

Now we have created a simple room. Now we need some light.
We will do this by creating a little fire as a source of light.

To have something the fire should stand on we need to create a small structure inside
our room.
Click the right mouse button on the cube builder button.
Enter height 64, width 32 and breadth 32 (as shown on picture below).

Now press build and then close.
A small red cube has been added and we need to place this on the floor inside our room.
In the "front view" window select the cube and hold down the "Ctrl" key and move the
mouse downwards (while still holding both the "Ctrl" and "Left mouse button").
Level the cube with the floor inside the room.

Screenshot

When this is done we need to select a texture for this structure.
Open the texture browser and select the "A_bsa" texture in the "Base" group.

Close the texture browser.
Now we don't want to remove mass from the world but to add some mass.
Press the "Add" button. Screenshot
A small cube as shown below should be seen

.
Screenshot

We also want to change the top of this one to make it look a bit more
fire "friendly".

Open the texture browser again and now select the texture "A_bs7" from "Base" group.

Close the browser again and apply this texture to the top of our newly created cube.

Screenshot

The fire itself is created using "sheet" builder.
Press the right mouse button on the "sheet" builder to open the properties dialog. Screenshot
Add the following information.
Height 64, width 32 and select X axis.

Then press the build button and close the builder window.
Move the sheet builder on top of the structure as show on the picture below.

Screenshot

To the fire we need a texture that looks like a fire.
Open the texture browser again.
Now we will load a new set of textures.
Select "file", "open" and load the texture set named "greatfire.utx".
A few wierd looking textures should come up. Don't worry they are animated and will look
normal.
Select the texture "ancflame2" and close the browser.

To add this "sheet" just press the "add special brush" button. Screenshot
Now we have some options to adjust.
Select "Masked wall" and check "Masked", "Transparent" and "Two sided". Also select "Non-solid".

When done press the "Ok" button.
A flame (upside down?) should appear.
We need to adjust this flame texture abit. Press the right mouse button on it and select
properties.
(If the flame did come up side down
move to the Alignment tab and press the "Flip V" button under rotation.)
Go back to the "Flags" tab and check the "Unlit" option.
(This prevents the flame from looking wierd when we add some lightsources.)

But this is not enough. Another flame texture is needed so it will look good.
We still have the sheet at the spot we just added the flame.
Rotate this sheet 90 degree so we get a crossing with the flame texture.
This should be done in the top view window.
To rotate hold down the right mouse button and the "Ctrl" button and move the mouse about.

Then add the other flame in the exact manner as above.
Also modify the properties as above. Flip vertical and check "Unlit".

Screenshot

Now to the lightsource itself.
Press the right mouse button at the flame and select "Add light here".
A torch should appear.
Move this torch in the middle of our flame.

Press the right mouse button on the torch and select properties.
Expand the "Lightcolor" and change the "LightBrightness" setting to 128.

Screenshot

When done the first room is more or less complete.
To actually play the level we need a players starting point.

Open the "Actor class browser" window by either selecting "View" and "Actor class browser..."
or pressing the "actor class browser" button. Screenshot
Expand the "NavigationPoint" and select "PlayerStart".

Place this in the bottom right corner by pressing the right mouse button on the floor and
select "Add PlayerStart here".
A joystick should appear.
If you need to move it a little, do so.

You also need to change the direction the player start is facing.
If you use the top view window and mark the player start you will see a red arrow facing right.
Hold down right mouse button and the Ctrl button and move the mouse so the arrow faces
to the top left area.

Screenshot

When all this is done only two things remain.
The first is to "build" the level. Select "build" from the menu and select "build options..."
Do nothing and press the build button.
The editor will actually create the room now and add the correct lightning.
When the progress bar is gone press the hide button.

The room should now look like this:
(Select "dynamic light" view if not Screenshot.)

Screenshot

Save the level and try it in UT.

Now we have completed the first part of the creation of a UT DM level.
From now on I will presume that creation of builder tools and opening texture/actor
browser is of no problem.


BB Drac - Unreal Tournament UED2 guide Tutorial DM part 2

Expanding The Level

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

NOTE:
You should have completed the first part of this guide before you proceed
with this part.

We want to create a level that is able to act as a fighting arena
for two players.

The room we have just created is not near big enough and we would also
need at least another starting point.

This is what we do...

To make alignment alto easier we first change the grid setting to 128.
This is done by changing the value located at the bottom right of the UED2
window.

Then create a cube builder with the size height 512, width 1280 and breadth 768.
Align this builder at floor level with the first room but 128 points to the left of it.
(That would be one square of the grid as the grid is set to 128. See picture for
detail.)
Screenshot

When that is done, open the texture browser and select the floor texture we used for
the first room (Group: "Floor" Texture: "FLOOR1").
Then subract this builder and a new room is created.
All four walls, ceiling and floor should have the same texture, but we want to change that.
We want new textures so you will have to load the texture set ancient.utx again.
Apply the texture "HIWALL1D" to all the long (east and west) walls and the texture "HIWALL1E"
to the short (north and south) walls (both textures from group "Panel").
Apply the "Aceilin1" texture from group "Ceiling" to the ceiling.

When done your room should look like this:

Screenshot

Now we must create the second starting point.
Just to things the easy way we will copy the first room and move it to the other side
of our newly created room.
Do this...

Mark the first room we created in part 1. Then press the right mousebutton on one of its
four borders.
A menu appears and you select "Polygons" and "To brush".
The builder tool should now be where the room is (red line).
Mark the new builder and move it to the left side of the big room exactly like the first
room.

Now subtract this room.
You see that it is exactly the same as the original room. It has the same textures and all.
Lets change the textures of the walls so we might tell the difference from them.
Apply the texture "A_stt" from the "Deco" group to all four walls.

Screenshot

We also want to add the flame from the first room inside this room as well.
The largest room also needs some light so we will add some there too.

Copy the first room again, as you did a few steps earlier.
Use right mouse button and select "polygon" and "To brush". Instead of moving the brush
we will intersect it.
(Details of intersect in other part of the UED2 guide.)
Press the intersect button Screenshot (under the "CSG" group).

You will see that the builder tool has copied itself like the flame and the structure
it rests upon.
Just move this builder to one of the corners of the largest room and press the
add button to create a new flame there.
Repeat this in the other corners of this room. Also place one in the center of the room
we created last. (Look at the picture below for more detail.)

Screenshot

Now you have all rooms looking good. Lets connect them.
Create a cube builder with this properties; height 128, width 256 and breadth 128.
To place this builder correct we need to change the grid setting to 64.
Level the builder with the floor and between the first and second room.

Screenshot

Select the floor texture as usually ("FLOOR1" from group "Floor") and subtract it to create
a small passage way from the startingpoint to the middle room.
Apply the texture "Walla6a" from the group "Deco" to the small walls and "Tilemos3"
from the "Trim" group to the ceiling of the new passageway.

Screenshot

Copy this room to the builder as you did twice earlier.
Then move this builder to the oppsite, connecting the middle room with the other
starting point. Subract it and we have a compelete passageway as the first one.

Screenshot

Now we should add the playerstart itself to the last room.
Select "PlayerStart" from the Actor browser.
(If you don't remember, it is located under "NavigationPoint")
Place it in the lower left corner of the room and rotate the arrow so it faces
towards the flame.

(In the side view of the level you see that both starting points
almost overlap each other).

Now we must create lightsources all the places we added the flame.
To do so we simply duplicate the first one.
Press the right mousebutton on the first torch and select "Duplicate".
Another torch should appear. Move this above one of the other flames.
(Vertical this torch is in the exact same height as the one we duplicated).
Duplicate the last torch you placed and place it above the next flame.
Continue until you have placed all that is needed.
(A total of six torches should exist now).

Screenshot

All we need to do now is to rebuild the level.
Select "Build" from the menu and "Build options..." to apply correct lightning.

Screenshot Screenshot

Save the level and try it.

Important note:
When you create a level, always place one or two player starts more that suggested
number players. This prevents that you get telefragged in the beginning.
As you will notice when you play against one bot on this level with only two
player starts is that you will get telefragged all the time.

This level is actually getting complete.
We need to add some cool things and some weapons first though.
Check out part 3 for more.


BB Drac - Unreal Tournament UED2 guide Tutorial DM part 3

The Water Bath

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

NOTE:
You should have completed the first & second part of this guide before
you proceed with this part.

A small level like this will be quite dull if no details and
cool looking gfx is added.

In this part of the tutorial we will add a little water pit
to spice up the level a bit.

To do so we need to dig ourselves a water-hole first.
Create a cube builder with the size height 256, width 256 and breadth 256.
Then place this cube in the center of the level and lower it so the top
meets the floor.

Screenshot

Now you need to load the texture set "ancient.utx" again. We do want the
water pit to look good.
Select the texture "UNCARVD2" from the "Base" group.
Then subtract the builder and a "hole in the ground" should appear.

To the walls you should apply the texture "HIWALL3D" from the "Panel" group.

Screenshot

To add the water texture we need to use a sheet builder.
Create a sheet builder with the properties height 256, width 256 and
axis horizontal.
Place the sheet just below the surface of our newly created hole.
(See picture for detail).

Screenshot

We also need a texture for this sheet.
Load the texture set "Liquids.utx". Select the texture "liquid6" from the
current group (the only group).

Then press the "Add special brush" button.
Select "Water" from the list under "Prefabs".
The rest of the settings should be as it is.

Then just select "Ok".
If the texture didn't appear at once you need to rebuild the level first.
Do so if needed.

It then should look like this:

Screenshot

All we need to do now is to add the water itself.

Open the actor browser and expand the "Info" option.
Then expand the "ZoneInfo" option and select "WaterZone".
Close the actor browser and move your view inside the waterhole in the
3D view window.

Press the right mousebutton and select "Add waterzone here".
Make sure the waterzone info icon is inside the hole and under the
water-texture.
(More info on water in other sections of the UED2 guide).

Screenshot

When that is done, rebuild the level.

Now test it...
Looks good? Thought so! : )

In part four of this tutorial we will add some weapons.


BB Drac - Unreal Tournament UED2 guide Tutorial DM part 4

Placing weapons

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

NOTE:
You should have completed the three preceding parts of this guide before
you proceed with this part.

This part of the tutorial we will place a total of three weapons and one item.
It is pretty easy so It will be short.

All items and weapons is listed in the actor browser under the title "Inventory".
Expand this and then expand the "Weapon" title.
You also need to expand the "TournamentWeapon" title to get to the UT weapons.

Select the first weapon we will place; "UT_FlakCannon".
Then move the view to the first room we created. In the upper right corner press
the right mousebutton and select "Add [weapon] here".
A flak cannon should appear.
You might need to move it up/down or to the sides to place it exactly where
you want it.
Then we need to place some ammo for this weapon.
Expand the "Pickup" title just below the "Inventory".
Then expand both the "Ammo" and the following "TournamentAmmo" title.
Select "FlakAmmo" and place two pieces beside the flak cannon.

Screenshot

Then move to the second starting point.
Select the "minigun2" from the "TournamentWeapon" title and place it
in the top left corner of this room.
Also place two ammo boxes besides this weapon.
The ammo is named "Miniammo" under "TournamentAmmo".

Screenshot

We also want to place a rocket launcher in the large room, close to the
south wall.
Select "UT_Eightball" from "TournamentWeapon" and place it between the two lights
and the south wall.
Also place one rocket pack behind it. "RocketPack" from "TournamentAmmo".

Screenshot

Protection might also be needed. Armor is found under "Pickup" and
"TournamentPickup". It is named "Armor2".
Select it and place it close to the north wall in the large room.

Screenshot

When you have done that you have placed three weapons with some ammo and one
armor.

Screenshot

Rebuild the level and try it.

In the fifth part we will look at bot pathing.
After that only one step is left to a complete level.


BB Drac - Unreal Tournament UED2 guide Tutorial DM part 5

Bot Pathing

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

NOTE:
You should have completed the four preceeding parts of this guide before
you proceed with this part.

In part five of this DM tutorial we will look at a fairly simple
but very complex part of level building... Bot pathing.

It is simple to do, but very hard to do perfect.

To place a pathnode we need to open the actor browser.
Expand the "NavigationPoint" title and select "PathNode".
Close the actor browser, this is all we need.

To place a pathnode you just press the right mousebutton and select
"Add PathNode here".

Place the first Pathnode infront of the lightsource in one of the
small starting rooms.

The pathnode itself should be an apple and at waist height above ground.

We need alot more than one pathnode.
Place one in the passageway just where it connects with the largest room.

Screenshot

When done, do the same with the opposite side of the level.
Place two pathnodes.

Then place one pathnode close and on each side of the waterpit.

Screenshot

Also place two at the sides of the two lights on each side in the largest room.
(Two pathnodes at the north wall and two at the south).

Screenshot

When done. Rebuild the level (make sure that "Define paths" is checked).

To view the paths itself press the right mousebutton on the title inside
the 3D view. Then select "View" and "Show paths".
(Bot pathing details in other parts of this UED2 guide).

Screenshot

Save it and play it, but as a spectator with only one bot to see if
the bot actually walks around the level.

In the next part we will look at level properties.
Adding music and a screenshot.


BB Drac - Unreal Tournament UED2 guide Tutorial DM part 6

Level Properties

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

NOTE:
You should have completed the five preceding parts of this guide before
you proceed with this part.

First off we need a screen shot. To do so we need to start UT.
Start a practice session playing this level as a spectator and with 0 bots.

When you grab a screenshot for your level it should show as much as possible so
we will grab on from the top corner in the largest room.

To grab the screenshot you press "F9". A file will appear named Shot###.bmp in.
in the system directory under UT (...\Unreal Tournament\System\...).
Quit UT and find this file and open it in any picture editor.
We need to resize this picture to it's right size.

First you need to cut out an equal sized square of the picture.
If it is 800x600 you should cut 600x600 and get as much as possible.
This is only to keep the right scale of the screenshot.
When done resize the picture to 256x256 and save it as a .bmp file.

Back to the UED2 and open the level.
First we will select a funky song for the level.
Open the music browser with the button Screenshot or select "View" and "Music browser" form the menu.
In the music browser select "File" and "Open" and load "Cannon.umx".

Now we want to import the screenshot.
Open the texture browser and then select "File" and "Import from PCX...".
(The file to import does not need to be in .PCX format).
Select the screenshot we created earlier in 256x256.
(Note: To see the .BMP file you need to select "Files of type: All files")
A properties box should appear.
In the package field type "MyLevel", "Base" in the group field and "Screenshot"
in the name field.

When done press "OK".

You should now have a texture named "Screenshot" in size 256x256
in the group "MyLevel".

Screenshot

Close both the texture and music browsers.
Open the Level properties by pressing "View" and then "Level properties".
What we need to add exist under "Audio" and "LevelInfo".

Under "Audio" you will only add the song itself.
Open the music browser and select "Cannon".
In the "Level properties select "Song" and then press the button "Use".
The song "Cannon" should appear.
Close the music browser and expand the "LevelInfo" title.
Open the texture browser and select our screenshot from "MyLevel" group.
Select "Screenshot" in level properties and then press "Use".
Close the texture browser.

Type your own name under author, "1-2" under ideal player count and
"UED2 DM Tutorial" under title.

(Under ideal player count it should actually be just "2" as you cannot
play with more or less players).

Now that this is done save the level and the DM tutorial is complete.
You have just created a simple level for the UT.

Part seven of this tutorial is only for those who want to know what
you have just done and some details about this level.


BB Drac - Unreal Tournament UED2 guide Tutorial DM part 7

Final Words

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

If you have completed part one through six you have just created
a very, very small one on one deathmatch level to be played in UT.

It has been made for learning purpose only and not for playability.
(I gather you have noticed that).

If we focus on layout and design the level itself is really lame.
First of all we only use five cube shaped rooms for the entire level.
Two small rooms connecting with a large room.
As you can see this will only allow players one route to each
side of the level which is not a good solution.

A level like this should always have alternative routes to make
it a lot more playable.

In the large room we created a water pit. In this level there is no
actual reason for it to be there.
It use more processing time then it is useful.
There is no item at the bottom and it is too easy to avoid falling inside.
(If we made a lava pit instead it would be a little bit better but still
no good enough).

As you can see the layout should always be logical and preferable connect
with more than one way in and out.
(This applies mostly to DM levels).

Using the texture and the fire is probably the best choice in a level
like this.
But, the way the texture is cut when we created the passage ways to connect
all rooms looks bad. Should not be like that.
A solution would be to create an archway that cut a lot better.
Textures that is cut in half will almost always look dumb.
On the other hand, a lot of 256x256 textures may look good even if they
are cut in half.

And to the last, bots.
Bots play as good as they can on this level.
Might have tweaked the pathnodes a bit to squeezed more out of the bots.
In a level like this it is very difficult.

With this final word I have simply evaluated this tutorial level to let
you get a direction of how levels should be.
Keep in mind that playability always comes before looks and details.

I hope this tutorial has been useful for you.
If you have any question don't hesitate to contact me.

End of this DM tutorial.


BB Drac - Unreal Tournament UED2 guide Console commands

Console Commands

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Using console commands is useful for a lot of reasons.
Debugging and play-testing comes to mind.

This list shows some of the commands available.

Command | Specific
Addbots [value] | Adds more bots to the game.
Allammo | You get a lot of ammo for each weapon you carry.
Behindview [X] | Change view to first or third person (value 0 or 1).
Demoplay [file] | Show a recorded demo. Use "demoplay [file]?3rdperson for behindview.
Demorec [file] | Start recording demo.
Fly | You fly instead of walking (more like swimming in air).
Ghost | No clipping and Fly mode.
God | Render you invincible.
Killall [class] | Kills all actors of a certain class
Killpawns | Kills all bots.
Loaded | Get all weapons (except warhead launcher).
Playersonly | All actors except players is paused (nice for screenshots).
Preferences | Opens the advanced options window.
Shot | Take a screenshot (same as F9).
Slomo [value] | Changes the game speed (1.0 is normal).
Stat cache | Show the status of the cache.
Stat fps | Show frame rate in milliseconds.
Stat game | Some game related values.
Stat global | Overall performance values.
Stat mesh | Show mesh values.
Stat zone | Visible zones.
Stopdemo | Stop current demo recording or playing.
Suicide | Kill yourself.
Summon [class] | Summons an actor of the specified class.
Timedemo 1 | Show Frame rate in second and average.
Viewclass [class] | View from the specified class location.
Walk | Resets Fly and Ghost modes.


Gringle's UED Tutorials

Gringle's Basic Tutorial

By: Gringle

The Redeemer

gringle@planetunreal.com

Tutorial 1

This is the most basic tutorial available to you at The Redeemer. It will cover the most basic of basics, the very raw beginnings of UnrealEd. If you're reading this, I know where you're coming from. I remember when I was a beginner too...I never thought I'd end up writing tutorials! Back in the day...Now, here's something important. For each tutorial I write, you MUST have UED2 open AT THE SAME TIME. If not, then you MUST print the tutorial(s) out. It will do you absolutely NO GOOD to just read the tutorials. This is a hands-on thing all the way. Well, anyways, let's get started, huh? Here's a list of what you'll need:

  • The latest working version of UnrealEd 2

  • An open mind

  • Actually, any mind is fine

  • Something to drink by the computer (preferably containing caffeine)

  • Time on your hands

If you've got all those, then we can begin. Open UnrealEd 2, except this time, open it remembering that you will know what you're doing. What, didn't think I'd know that you opened it and tried to do something? When it's open, (yes, it takes that long every time) we can start.

If everything is loaded correctly, this is what you should see:

Daunting, isn't it? And yet this is where everything UnrealEd comes from. It is the gene pool of Unreal Tournament. This is where CTF-TwinValley was made. The place where DM-UrbanArena][ was created. This is where you, as of yet unknown, will one day make your magnum opus. No, that isn't a gun, it's a phrase I learned from Charlotte's Web.

So, how to move about in this virtual expanse? Well, from here you can see four main viewports: starting with the gray one above the one with blue lines, I will go clockwise, ending with the blue-lined view. The first grid, above the blue lines view, is the "Top-Down" view, or, X axis. Think of this as looking straight down on top of your map. To the right of that is the "Comin' At You" view, or, Y axis. Think of this as looking at your map "head-on". Below that is the "Mario", or "Side" view. This is the Z axis. Think of this as like a platform game. You are viewing the map directly from the side. And finally, we have the "blue lines view", or the 3D view. This is where you can dynamically move around in a fully rendered version of your map. It's like being in specator mode in UT, except in that little window and you can move through walls :) Okay, so it's more like "ghost" mode.

Now I'm going to have you practice moving around in the views. First off, the easiest views to move around in....the grids (I will refer to the gray-ish 2D viewports from now on as the "grids"). Let's go to the X grid, or the "Top-Down", remember? Simply left click and hold down the mouse button in there. Now move the mouse around! I think you got the hang of it. Try this in each of the other grids. Now we come to the 3D view, which is quite a bit more complex. This is good, however, because you want to be able to maneuver your way around your map easily and quickly. First, use the left mouse button like you did in the other grids and move around. Yes, it's like driving a car, huh? Try that for a while. Now, do the same thing, except with the RIGHT mouse button. It's like craning your neck to look all around you. Finally, get the view back to a level position, kinda like how it was when you first started UED2 up. Now, hold down BOTH the left AND right mouse buttons and move around. This is like being in an elevator when you move the mouse up and down, and like strafing when you move it left and right. Practice all of these moves in the 3D grid (don't worry, that's all there is to moving in the 3D grid! Whew!). Make sure you feel comfortable with moving around; otherwise, you will kick yourself for it later. Now, back to the 2D grids. Yeah, I know, but there's just one more move. Hold down the left AND right mouse buttons (just the right mouse button does nothing in the 2D grids), and move the mouse up and down. This zooms in and out.

Well there you go. That's all there is to moving around. Practice this till you feel comfortable and you don't even have to think about it, cause we got some more heavy concepts coming up. If it's lunchtime where you are, you might want to take this opportunity to go eat and come back fresh. Hey, what do you know! It's lunchtime here! Excuse me while I go grab a bite to eat.

Well, I'm back. Now let's move on to the core of UED 2.

In the world of UnrealEd2, there is a supreme god. It can be neither created nor destroyed. It can be reshaped in an infinite number of ways, flattened out to a miniscule height, or expanded to be thousands of thousands of virtual feet high. It is called The Red Brush. That's right. Everything inside of UED2 is a "brush" or an "actor". You know the Shock Rifle? Actor. The little bases that the flags sit on in Coret? Brush. The trash cans in DOM-Condemned? Actors. The elevators in DM-Fractal? Brush. Simply put, a brush is anything that is made with the red brush. Confusing, ain't it? Well, let me see if I can show you. On the left hand side of your screen, there are a bunch of buttons. I'll explain what they all do in the next tutorial, but right now, I want you to click on the one that looks like a cube under the header "Builders". Hey! You've just summoned the god of UED, the red brush. Let me get something clear. The red brush does not look like a cube. You've just told it to look like a cube. It is a shapeshifter, you see. Now, using your newly aquired camera skills, move around the cube and look at it. Interesting, huh? In your 3D (or actually, in any) view, left click once on the red brush. It turns even redder. This indicates that it's highlighted. Here's where it gets a little difficult. In order to make maps, we must be able to manipulate the red brush to make it go any number of places with relative ease. This means we have to learn how to make the red brush move. Make sure the cube is highlighted (yes, I know I'm interchanging the words "cube" and "red brush" a lot, but as long as you understand the red brush's concept, then me calling it a cube should not confuse you). In the 3D view now, hold down your Ctrl (control) key along with your left mouse button. Move the mouse left and right. It moves! Notice that moving the mouse up and down does nothing here. Now, try the same thing, except use the right mouse button and go up and down. Notice that moving the mouse left and right does nothing here. Now, do the same thing, except hold down, you guessed it, the left AND right mouse buttons. Move the mouse up and down, and the red brush moves accordingly. That's it for the 3D grid. But here's a twist....try doing everything I just said, but hold down SHIFT instead of control. The camera will move with the brush. Useful, huh?

Now, on to the 2D grids. This is, unfortunately, quite more complex. We'll start simple, however. Stay with me guys and girls...this is the hardest part of mapping, I guarantee you:--learning--. Once you're done with this tutorial and you've practiced a lot, the worst is behind you, really. Anyways, let's go to the X-Axis or Top-Down grid. Hold down control (or shift, your preference), and use the left mouse button to move the cube around. Simple. Now, use the right mouse button: the cube rotates. Starting to see all this? Now, you might say, "Hey Gringle, nothing happened to the cube in the 3D or other 2D views! Well, this is because to see everything happen in real time, you need some extra processing power. If you've got a nice computer with lots of RAM, click on the little joystick icon on the toolbar above each view. It will be surrounded by a green haze. Now rotate the cube. Aha! But you must understand that you are working in 3D here, and the next two grids are important for understanding what happens to the cube when you move it. With the joysticks still turned ON, use the right and left mouse buttons in the next two grids and see what happens. Take note of these and practice. I'd say you should take a full 15 minutes to half an hour practicing with the camera and moving around a simple cube.

Well folks, that's it for your first tutorial. You've survived. I have to ask you to practice practice practice, and don't come back to the next tutorial until you feel quite comfortable with all that I've showed you today. And never fear: the next tutorials will have more pictures and will be longer....this was more your intro to UnrealEd. In just a month or so, you could be the graduating class of 2000. Thanks for stopping by and remember: don't get discouraged: the best is yet to come!
--Gringle


Gringle's UED Tutorials

Harder Concepts

By: Gringle

The Redeemer

gringle@planetunreal.com

Tutorial 2:

Hello and welcome to the second tutorial at The Redeemer. Make sure that you have completed the previous tutorial before starting this one. As always, make sure UED2 is open while you complete this tutorial. It will do you ZERO good to just read this. Let's begin. Here's what you'll need for this lesson:

  • UnrealEd 2

  • Completion of the previous lesson

  • An IBM(c) compatible mouse

  • 4 MB RAM

  • A wheel of cheese (if you don't have it, just get a canister of Cheez Whiz...make sure not to sniff the aerosol can afterwards though...you know, Drain Bamage and all that).

Ready for the next tutorial? I am. Let's get started.

First, we're gonna learn all those little buttons on the left hand side of the screen. Open Ued2 if you haven't already. Now, see the little indented camera? I'm going to call that number one. See the weird cubish thing to its right? That's number 2. And so on. Don't worry if you don't understand the terminology...I'll be going into that shortly. The buttons that are highlighted in green are ones you'll have to remember specially as a beginner. Just remember what the other ones are. Here are the buttons in order:

  1. The camera: This is you. This is "camera mode". Don't touch this, at least for a while.

  2. Scale Mode: This is often a beginner's crutch. It is used as a shortcut to scale brushes. Don't touch this one either.

  3. Rotate Mode: This is pretty useless unless you're really lazy. Don't worry about this one.

  4. Texture Pan Mode: This is also for lazy people. Oh, be quiet, don't tell me you're lazy.

  5. Texture Rotate Mode: See Texture Pan Mode.

  6. Vertex Editing: This is very, very useful, but as a beginner you shouldn't worry about it quite yet. See? All you really needed to know in the first group was camera mode!

  7. Add Brush to World (or, simply, Add): Ahhh!! This button is incredibly important! You will wear out this button using it. You will use it more than any other button. Scary, huh?

  8. Subtract Brush from World(or, simply, Subtract): The only button that you'll use more than this one is Add Brush to World. Quite important.

  9. Intersect: This is more of an intermediate tool. Don't worry about it, but file it away cause you'll need it soon.

  10. De-Intersect: Like its brother intersect, just remember that it's there.

  11. Add Special Brush: This button is important. You use this to tell the editor if the brush you're adding is special or not. Yeah I know that sounded like gibberish to you. Chill, I told you I'm gonna get into that stuff later. Jeez.

  12. Add a Mover: Yeah, this adds stuff that moves. Important, but not for a beginner like yourself. This is early intermediate stuff. That's it for the CSG group. Pretty important, huh?

  13. Clipping: For the next three, you really shouldn't even mess your brain up trying to know what they are. They have to do with clipping brushes, like that means anything to you.

  14. See Above

  15. See Above

  16. See Above

  17. Build a Cube: This makes the red brush turn into a cube with a size that you specify.

  18. Build a Sheet: This makes the red brush turn into a sheet with a size that you specify.

  19. Build a Cylinder: Yeah, it turns our friend the red brush into a cylinder.

  20. Build a Cone: Like I had to tell you, it turns the red brush into a cone.

  21. Build a Sphere: Sigh....turns the red brush into a sphere.

  22. Build Curved Stairs: Turns the red brush into a curved stair set with dimensions you specify.

  23. Build Spiral Stairs: Turns the red brush into a spiral stair set with dimensions you specify.

  24. Build Linear Stairs: Makes the red brush turn into a set of linear stairs for you (for those of you who failed geometry, linear means straight).

  25. BSP Based Terrain: Ummm....Well, since you'll have TerraEdit when you're ready to create complex terrain, it renders this option useless.

That's it for the buttons! Hooray! Don't stop now, we've barely scratched the surface of this tutorial! Soon, we'll have created our first room! Joy! This is a good time to eat some cheese (or squirt cheez whiz if you don't have cheese). On to the important stuff. Let's see some action, already!!

Now we begin. It's time to make your first room. Before proceding, make sure you've got all the green buttons at least down (no, that does NOT mean push any of them!!!), and you are extremely proficient with the camera and rotating the red brush.

Okay, right-click on the build a cube button. You should see a dialogue box with lots of scary numbers. This is where you customize how your red cube brush takes shape. Right now, we want to make a 512(height)x512(width)x512(breadth) cube. So, enter in the appropriate dimensions, and click build. You should see a big old cube there. This cube will be a room soon. Now, I want you to click on the little button that looks like a painting on the main toolbar. This is called the texture browser. When we make rooms, we want them to have textures on them, don't we? Yes. Yes we do. After you click on it, you will get a seperate window with a few options.

None of those strange textures look like you could "wallpaper" a room with them do they? So, on the toolbar in the texture browser, click on File--->Open. Right now, from that popup window with all those texture sets, scroll to and select Ancient.utx. Open it. Ahh, now we have this:

You will notice that the top drop down menu in the texture browser switches between "packages", or, ".utx" files, while the one below that sorts the different textures within one package. The weird arch textures we have on screen right now just won't do. So, let's click on the second drop down menu and select "Wall". Now click on the texture named "BRIXG2". It will be surrounded by a green box, indicating it is the selected texture.

Now, it is time to create the room. Get ready. With the texture highlighted, close the texture browser, then click on the SUBTRACT button to "carve" away a chunk of the grid.

Congrats man, you just made your first room. Move the red brush away from its current position. Notice that a yellow square where the red brush was. This is the color of a subtracted brush. That's right. A subtracted brush can be deleted and created. Can you see how the red brush left behind the yellow, subtracted one? Now, every time, when making your map, you do something big, like creating a whole other room, you want to do what is called "Rebuild the Geometry", or just "Rebuild". So, on the main toolbar, click on the picture of a cube (the one next to the picture of a lightbulb). UED2 will work quickly and the geometry will have been rebuilt. This balances all sorts of stuff when your map gets more complex. Now, Rebuild's cousin, Lighting, must be done. What Rebuild does for the geometry and structure of your map, Lighting does for the lights and other effects. Click on the lightbulb now. Ahh!! Everything went dark! Perhaps this is because we have not added any lights?

However, before we do that, I don't like that the texture on every wall is the same. But how can we change this if everything is dark? Simple. You'll notice that in the 3D grid, there are a row of strange looking cubes running along the top. The one that is highlighted green right now is the "Dynamic Lighting" view. Click on the cube immediately left of that one, Texture View, and it all becomes light again! This is because this view simply shows you the textures, pure and simple, without any light sourcing.

Re-open the texture browser. Now, where we have "Wall" selected, choose "Ceiling". Now, without closing the texture browser window, click on the ceiling of your room. It is covered in a bunch of blue dots. This indicates that that texture is highlighted. Now, click on the first texture in the ceiling set. Bingo. You get a tiled ceiling. Now, where it says ceiling, choose Floor. Highlight the floor of your room, and then click on the texture "Floor2". Perfect. Close the texture browser and click on the floor again to deselect it. This is what it should look like:

Was that a lot or what? Now for some lights.

Right click in the middle of your ceiling. Move your pointer to Add Light Here... Now click.

A little icon of a torch appears. But no apparent change! Can you figure out why? Yep, we're still in Textures mode. Click over to Dynamic Lighting. Yep, there is the source. Now click on the Lighting button to make the light source softer and more realistic. It should be something like this:

This would be a good time to save. Click on File---->Save As... and name it something unique like DM-Test. Now, right click on the cube brush again and change the dimensions to 64x128x128. Use the 2D grids to line it up like so:

Now open the texture browser and select Base where it says Floor right now. Choose A_BS3 and click the ADD button. A red block will have appeared. In the 2D views, it shows this ADDED brush as blue. So: All powerful creator brush = red. Subtracted brush = yellow. Added brush = blue. Now we want to have a little flame sitting on top of this block. However, a flame would not be a brush, like we have been making. It would be an actor. So we must venture into the land of Classes. Next to the texture browser button there is a little picture of a pawn. Click on it. Whoa! Lots of stuff here.

Now expand Light by clicking on the plus sign next to it. Highlight TorchFlame. Now, right click on the middle of the block and click on Add TorchFlame. Use the views to line it up. You know what to do.

Now, we should add a weapon. Let's add a Pulse Gun cause it's tha coolest. Close up the Light subcategory by clicking on the minus sign. Now, expand Inventory. Then from there go to Weapons. From there, TournamentWeapons. Then, highlight the pulse gun and add it in the room somewhere like you did the torchflame. Here's what your room should look like now:

Rebuild the Geometry and the Lighting, then save. Now we need one last thing to make it playable. This is something called a PlayerStart. It is where all players spawn from. In the classes menu, expand Navigation Point, then highlight PlayerStart. Add it in the room. You should have this:

Guess what. I hereby certify you a beginner. You have surpassed your newbie status and you have the skills to start learning the real stuff :) You might want to run through this tutorial a few times to get the hang of it. Congratulations and good luck. Go for the next tutorial when it is done.
--Gringle


Your first deathmatch level

By: Gringle

The Redeemer

gringle@planetunreal.com

Tutorial 3 :

So, you're ready to take on the bigger tutorials now, huh? You've got down the whole camera and buttons thing. You can move about with ease. Rotating the red brush is not even a challenge. Then, I think we are ready to create our first Deathmatch level: DM-TrainingArena. I will be touching on concepts like added/subtracted brushes and what they mean here. We will also be focusing on harder things like texture alignment and even some colored lighting. Don't worry, it's all fit for a beginner like yourself. WARNING: THIS PAGE WILL TAKE A WHILE TO LOAD. BE PATIENT.

Before we begin, I just want to say that you will not be able to release the map you are about to create. In fact, even playing it by yourself won't be much fun since we're just learning the basics. So if I see this map submitted to The Redeemer or Nali City I won't be happy :). Here's what you'll need for this lesson:

          • UnrealEd2

          • Completion of the previous two tutorials

          • Comfort in moving the camera and rotating brushes

          • Tenacity (perserverance) [stick with it]

          • The Food Network with Iron Chef on

          • A good Mp3 player like Sonique. Right now I'm listening to "Clubbed to Death" from The Matrix soundtrack. Good old Bad.Mojo and Pacman pointed me in the direction of that one. What? We're back on? Oh, ok. Ahem.

          Down to business. Open UnrealEd2 now, please. Use the texture browser to load "UTTech1.utx". UTTech1 is an excellent texture set though TheMadMonk and I tend to overuse it like mad. This set will make up the general theme of our map. After it's opened, make the red brush into a cube that is 512x512x512. No, I didn't say subtract it. Now, back in the texture browser, "Base" is the texture set displayed within UT Tech 1. Beginners love to hang on to Base textures because they are so easy and simple and all purpose to use. But I'm not going to let you get into that habit. Check the box next to the Base drop down menu that says "All". Now, we see a listing of every single texture within UTTech1. Scroll down to "ClifBak3" (the one without the window). Highlight it. Now subtract your room. You should have this:

          Add appropriate textures from the floor and ceiling categories respectively. Say, oh, I don't know...NMCeiling2LT3 for the ceiling and PMBFloor-B for the floor. Okay, now we want lights. Wait! If you just add lights randomly your map is gonna look worse than Oprah when she finds out that the 2 for 1 at Kentucky Fried Chicken is gone. We need to find an appropriate source for the light. It needs to come from somewhere. So, let's open the classes menu. Expand Decoration. Go down to "Lantern2". Highlight it, then add it to one of your walls by right clicking and saying "Add Lantern2 Here".

          Make sure they are even by using the grid views. Can't have lopsided lanterns now, can we? What's that you say? Lanterns don't fit in with the theme? Well, I say they do. So there. Now, add a light close to each of the lanterns, then rebuild the geometry and lighting. You should have a close approximation of this:

          Now save the map as DM-TrainingArena. Add a PlayerStart like I described in the previous tutorial. For those of you too lazy, it's in the classes menu under NavigationPoint. A PlayerStart is where you spawn from. Now, in the Top-Down view, or, X axis, highlight the playerstart actor. A red arrow will be pointing out of it. This is where you will be facing when you spawn. Stick it in the corner with the arrow pointing out. Like so:

          Now the map is technically playable. Next let's add a hallway leading to another room, huh? Resize the red brush to 128x300x500. Position it off of the main room like so:

          What's this?! When you zoom in nearly all the way, you can see that it doesn't line up perfectly. That's because the grid is set to 16 units and 16 doesn't evenly go into our numbers. So how did I get it like the picture above? Right click on the grid. Hold the cursor on Grid--->1 Unit and click. Now line it up. When you are sure that the red brush has been lined up parallel to the floor of your room, and it is positioned as you see above, click subtract. This "subtracts", or, "cuts away" more of the grid to extend a hallway running away from the room. Texture the ceiling and floor of the new hallway like you did the original room. To further your knowledge of the concept of the "subtracted" brush, we're going to do an experiment.

          Resize the red brush to a size of 10x30x10. Position it at the floor of your hallway, with the edges lined up like so:

          Now subtract. See how this carves a little niche into your wall? If nothing happened, zoom in closer to make sure it's lined up perfectly. Don't worry, that can happen a lot till you're used to it. Rebuild Geometry/Lighting. Notice how the floor looks kinda messed up in the spot where the hallway starts?

          To fix this, we need to do something called texture alignment. I will go over more advanced texture alignment in the more intermediate tutorials. But for now, we just don't want it looking like crap. Click on the floor of the hallway. Now, hold CTRL and left click the floor of the first room. They should both be highlighted. Now right click on them and click on "Surface Propertied (2 Selected).

          Now we've got a nice little dialogue box.

          That's a lot of crap to look at. But we're not concerned with any of this...yet. Click on the tab "Alignment". If nothing happens, this is due to a small glitch in UED2 that doesn't make the tab click over every time. Just reclick on "Flags" and click on "Alignment" again. If you have no idea what I just said don't worry about it. On the alignment screen we see this:

          See the little button in the lower left corner? Align to Floor? Yeah. That's the one we want. Click on it and close the dialogue box. Rebuild Lighting. This is what we have now:

          All aligned! Now, back to the niche. We're gonna make it a little light source. Switch to textures mode by clicking on the little cube next to the highlighted one on the menu for the 3D window (Uhoh...that was a word sandwich. Maybe I should just show you. It's the one where you can kinda see my mouse pointer. That's what you should click on. GET IT??!!).

          Now everything should be light again. Go down to the niche and open the texture browser. Now choose "Light" from the second drop down menu. With the texture browser open, click on the far surface on the niche so it looks like a light will be there. Now click on the texture "ACLIFLT2". Uhm..that doesn't look anything like what it shows in the texture browser huh? That's because our niche is too small. So, it's time to right click on the newly textured surface to change that. You should have this:

          This time we're concerned with the Scaling section. Click on the "Simple" drop down menu. Now, the scaling the texture is automatically set to is "1", or, "1 times the original size". Let's set it to....point 125, or ".125". Now click Apply. Well, that's better but it still isn't lined up right. We'll have to pan the texture manually then. Oh shut up, it's not that hard. See the little buttons 1, 4, 16, 64 in the Pan section? Yeah. I won't make you do it yourself, for now, so I'll tell you how many times to push the buttons. "V" is height. "U" is width. Okay, here we go: Click V(16) 5 times. Now click V(4) 6 times. The height is now good. Now click U(4) once. Now click U(1) twice. See what we did? It's all lined up now. Click hide on the dialogue box. Now, add a light right in front of this light. Rebuild Geometry/Lighting and switch to Dynamic lighting instead of textures mode. Don't make me show you the toolbar again. I won't do it. You should have this:

          Not bad at all. But do you notice that the light texture is all dark? It shouldn't really be like that if it's a light. I mean, can you imagine a lightbulb casting a shadow onto itself? So, we'll have to mess with some "Flags". Right click on the niche's light texture again. Surface Properties. This time click over to flags. If the tab switches but the screen doesn't change, again, this is a little glitch. Just click back and forth a couple of times. The flag we're looking for this time is "Unlit". This will make it so that light doesn't affect it at all. Check off unlit, then click "Hide" and rebuild lighting.

          Better. Save the level. Now, here's what I want you to do. Start Unreal Tournament. Set up a practice game in any map with ZERO BOTS. Once you're in the game, exit Unreal Tournament again. Done? Okay, now, click on the little icon of a joystick up by the main toolbar (where the texture and classes browsers are). This is the "Test Level" button. It will throw you right into a game. As long as you set a game with 0 bots, you should encounter any problems.

          Ahh, was that fun? I didn't think so. Let's keep building. Now resize the brush back to 128x300x500. Make an L shape in the hallway like this:

          Now, make sure that the brick texture is selected and the bottom of the hallway is all lined up, then subtract. Texture the floor and ceiling like the other two rooms, then rebuild lighting and geometry. BONUS:Try and align the floor and ceiling yourself for extra credit!

          Save your work now. Okay, now let's resize the red brush to 550x900x900. Using the top down view only, line it up like this:

          Now, with the brick texture selected, let's subtract. Oh crap. Our hallway sticks out in the middle of the wall! But that's okay...we've got STAIRS! Yeah!! Stairs!! Gooo stairs!! I love...oh...ahem. Anywho, right click on the LINEAR stair builder.

          The first thing we want to change is the StepWidth. This is simply how wide the staircase is. It is set by default to 256. Our hallway is 300, so change that to 300. Step height you should almost always leave alone. This is not how tall the staircase is, as you might think, but in fact it is how tall each individual step is. A bot in UT can only go up a height of something like 20, so you wanna leave this at 16. What we want to change here is NumSteps, or, the number of staps. Let's make it 14. Now click build. Using the Y axis or "head on" view, line up the stairs so that the top step is aligned to the hallway. The bottom of the stairs will overlap the bottom of our room a bit, but that won't matter. Line it up like this:

          Now, open the texture browser and choose "base" from the second drop down menu. Highlight CLIFROK1 and ADD the staircase. Now texture the floor and ceiling of this new room like the others. Now, add some more lanterns around the room and then add one light to each one. 3 lanterns should be fine. Remember: classes menu---->decoration---->Lantern2. Rebuild geometry, lighting, then save. Hopefully you've got something like:

          Go ahead and play it real quick if you want. Now, personally, I like the color blue. Let's make some of the lights in our newest room blue. Click on one of the lights on the far wall. When it is green, this means that is highlighted. Now, hold down CTRL and left click once on the other light. Now they are both highlighted. Note when I say light, I mean the icon of a torch, NOT the lanterns. Now, when they are both highlighted, right click on either of them. Click on Light Properties (2 Selected). We're looking to change them to the color blue. So, let's expand (what else) LightColor. Now, you could input the Unreal Color Wheel values like us old farts used to have to, but instead, just click on the little button that says "color". Now select this color:

          And close the window. Ta da! Rebuild everything and save, just to get in the habit. Now we're going to add the final hallways and rooms, then we'll move on to weapons. And then, I will tell you how to make bots work with it JUST for fun, but I won't explain anything about it. I just want you to be able to play the map if you want. You probably won't, but...;)

          Okay, here we go again. Resize the red brush to a size of 180x160x400. Place it like so in the top down view (make sure it is aligned to the floor):

          Now, with the brick texture selected, subtract. Texture the floor/ceiling accordingly. Now, resize the red brush to 550x700x700 and align it to the floor. Now position it in the top down view like this:

          Subtract with the wall texture selected and do the ceiling/floor like you learned. Now add a lantern in each of the corners and add a light to each of them. Then make two of those lights the same color as the other room. You should have something akin to this:

          Rebuild Geometry/Lighting. Save! Now, we're gonna try something sneaky. Resize the red brush to 200x200x600. Position the red brush like this:

          With the wall texture selected, subtract. Make SURE it's aligned like above. Now return the brush to a level state. Resize it to 550x600x800. Align it like you see below and subtract.

          Now texture the ceilings and floors for the slanted hall and new room like the others. Now, those hallway walls are skewed in quite a strange way. So select them both, go to their properties, then in the alignment tab, choose "wall direction" and then "wall pan". Now, in the new room, add four more torches with 4 lights, two of them blue. You know what to do. Rebuld everything and save. You should have something like this:

          Note that the floor of our newest room and the floor of our VERY FIRST room MUST be parallel at this point. Now, resize the brush to 200x200x300. Align to the floor and like below:

          Subtract with the wall texture. Now, resize to 200x200x800, align like below, texture the two new halls appropriately, rebuild lighting, geometry, and save. Toss a 4 lights along these halls...2 of em blue.

          Almost done guys, stay with me. Resize the brush to 550x400x400, align it to the floor and stick it at the end of the hallway, subtract, texture, 4 lanterns, 4 lights, two blue: like so:

          Rebuild everything and save. Resize the red brush to 200x200x700. Align it to the floor and like this:

          Subtract with the wall texture, texture the floor and ceiling, toss 4 lights in, two blue, rebuild it all and save. Finally, resize the red brush to 200x200x500 and join it to the first room. Texture accordingly.

          Rebuild and save. Now, open the classes menu and expand Inventory. Expand Weapon---->TournamentWeapon. Add some weapons like lanterns around the map as you see fit. See if you can find where ammo is in the classes menu (hint: it's in the inventory menu). The rest of this tutorial is optional, in case you want it to work with 3 other bots. Go to the classes menu, expand NavigationPoint, and select SpawnPoint. Add it and 3 PlayerStarts like a lantern in a 3 other rooms. Rebuild it all and save. You're done. This is your first DM level. Be proud, I know it wasn't easy. I hope this tutorial helped you. Go ahead and experiment while I do the next tutorial. Thanks for completing this, and happy building!
          --Gringle


Beginners

Beginners UnrealED2 Tutorial

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Contents

1) Preparation
2) The Interface
3) Building your first room and navigating
4) Textures
5) Adding objects
6) Level Properties
7) Rebuilding

Introduction

I’ve had a number of requests by people to explain the very basics of using the Unreal Editor. In this tutorial, I will assume that you know absolutely nothing about the editor or level editing in general.

Preparation

Before you even start to create your maps, you need to know if the editor is working. If you’ve got it straight off the CD then I’m sure it won’t be, and you’ll need some files to get you started. If you're reading this tutorial then I assume you already have UnrealED version 2, but just in case you haven't you'll need to get the latest patch for
Unreal Tournamnet. A the time of writing this, the latest patch is 418 and you can get that here.

Once you've got the patch (I'm also assuming you've got a zipping utility), just double click it and follow the instructions.

As you begin to use the editor, take care and don’t get frustrated with it. UnrealED2 seems fine so far but the original version was a Beta version, which means that sooner or later it would give you a hard time. If you did
something it didn’t like, it sulked and would crash without giving you a chance to save your work. So, make sure you save often, believe me, you’ll need to!

The Interface

Now you should be in business. Open up UnrealED and once its finished loading in (it can be slow), you should have a screen that looks like this:

If this is the first time you’ve done anything like this (like it was for me not so long ago), this must look like you need a degree in astrophysics to make your own level. Don’t worry! If I did it, so can you. It’s easy when you know how, and after this tutorial you’ll be running around in your own level :)

First you need to know the very basics of what you’re looking at. The screen is divided up into 2 main sections:

1) The toolbar on the left with all those strange squares and circles.
That’s your “browser” toolbar from which you can make "brushes". “Brushes” are things you need which make a variety of geometric shapes which are the basis for creating rooms.

2) The large area which is split into 4 smaller windows.
This is where you can actually see what you’re making as you progress. You’ll notice that 3 of them are grids, and one is a black window. The 3 grids are the 3 different ways of viewing your map straight on.
The top left grid views it directly from above. The top right grid views it from the side, and the bottom right grid views it from the other side (x and y axis). The black window is a 3D view of the map almost as you would see it in the game. You’ll soon see what I mean as you start building.

This might still sound like rocket science, so it will probably help to start building something right away.

Building your first room and navigating

1) First, find an icon in the left hand tool bar that looks like a pale blue cube (the 5th one up on the left of the toolbarabove the cylinder shape, if you hold the mouse over it, it will tell you it's a cube).
Left click on that and you should see the red outline of a square appear in the white 2D grid views. In the black 3D viewer, it will appear as a red outlined cube. This is your “building brush”.

2) Now look for an icon that looks like a dark blue square overlapping a light blue square (its called "subtract"). Left click on that and you should see the cube in the 3d view with white bubbly sides. What you’ve done now is “subtract” that brush from your world. What does that mean? Well, imagine that what you’ve started off with is
a gigantic solid block. By “subtracting” that brush you’ve just cut a big cubed hole into that block which has made your first room.

3) At this point you might want to have a closer look at your block with those 4 windows in the center of the screen. Left click in any of the 2D views and with the mouse button still pressed down, move your mouse
around. You should find that the grid is moving around. Now hold both mouse buttons down (still in one of the 2D grids) and move the mouse up and down. You should now see your red square zooming in and out.

4) Now for the 3D view. Left click and drag the mouse the same way as you did with the 2D views but this time in the 3D view. When you move left to right you will see it turning as if you swiveling on the spot. When you move the mouse up and down, your block should move back and forth. Now click both mouse buttons and drag the mouse from left to right. You’ll see the block mover from left to right as if you’re strafing. Now move the mouse up and down with both buttons clicked and you’ll see the block move up and down.

You may need to practice these moves for a while until you start getting used to it. With all those combinations you should be able to get a good look at your block from all directions.

Textures

I think you’ll agree that those white bubbly walls look pretty ugly, so now let's choose a nicer pattern for the walls, floor and ceiling. For this you need to open up the "texture browser"

1) There are two ways to open up the texture browser:

a) Choose "View" from the menu bar at the top and then select "Texture browser" from the drop down list, or

b) Click on the icon just underneath the menu bar that looks like a small portrait.

Once you've done that, a new window will appear which you can resize, minimize or whatever. From the menu bar you can choose how large the textures are to view by selecting an option from the "zoom" option.

2) Now you need to find some interesting textures. From the menu in the texture browser Choose “File” then "open" and you’ll see a browser appear. It will display a nice selection of files all which contain a wad of textures. Choose “Ancient.utx” (I like these ones) and click on “open”. You’ll then see a different set of textures appear in the window. You’ll also notice that the little display boxes above the textures have changed. One contains the word “ancient” showing you which file you’re using and the other one contains the word "Arches" which is showing you what type of textures you're looking at from that pack. Click on the arrow to the far right of the box that says "arches" and you'll see a drop down list showing you all the different types of textures there are such as "door", "wall", "ceiling" etc. You don't necessarily have to use a "wall" texture on your walls, but they're split up into these sections to make it easier for you to find specific textures.

Before going any further, make sure you can see the textures in the texture browser without obscuring the 3D view of your editor's main screen.

3) Now we need to actually apply that texture to our room. In the 3D view left click once on one of the walls and you should see the wall surface shade slightly showing that it has been selected. Now keep you’re finger on the Ctrl button and select another wall. You’ll notice now that the Ctrl button allows you to select more than one thing at a time. Select all of the walls (One of the walls will probably be obscurred from view so you will need to move around in there to select it). Now choose a texture you like and left click once on it, it should have a gray border around it now, and you should also see that the walls have automatically changed their appearance. You can use the same technique to change the ceiling and floor.

When you've finished using your textures, minimize the texture browser so that it won't be in the way for our next step.

Adding Objects

Now that you’ve got a very basic room created, you can add some “objects” to it. For the purpose of this tutorial we’ll add a light, a monster and a player start. The following steps will teach you how to add an object and move it around, and it will also introduce you to the way in which you can change its attributes.

1) First we’ll add our light. To do that, aim your mouse at the floor of your room in the 3d viewer and right click. You should now see a drop down menu. Choose the option called “Add Light here” and you’ll see a torch icon appear where your mouse was pointed. Click on it once again and you should see it turn green which indicates that you have selected it. Press the Ctrl key down and in the same way you navigated around the views by clicking and dragging you can move this torch around inside the room. Try moving it around in the 2D views too. You should start to get an idea now of how the different views relate to each other now. Position the light in the centre of your room.

2) Now lets add a monster. To do this you’ll need to use a new browser which shows you a selection of "actors". You can select this browser by choosing "View" and "Actor class browser" or by left clicking on the small icon that looks like a chess pawn.

Another new window will appear that should look like this:

Click on the little plus sign next to the class called “pawn” and you should see it expand some more. Do the same thing with the one called “Scripted Pawn”. Left click on “Slith” so that it’s highlighted. Now, in the same way you did with the light, point your mouse where you want the Slith on the floor of your room and right click. Because you highlighted the Slith actor, you should now see “Add Slith here” on your menu. Choose that and you should see one appear in your room.

Now, suppose you wanted the Slith to face a different direction. In your 2D view that shows you the view from above (the window above the 3d view), you should see the Slith as a brown outline. Left click on it and it will turn green. You’ll also notice that it has a red arrow pointing in the direction it's facing. With the Ctrl key pressed down, press the right mouse key down and drag the mouse from left to right, you’ll see your Slith swivelling.
Just put him in whatever direction you want him.

Lets go a step further! With the Slith still selected (showing as green), Press F4 or right click on it and choose Slith properties. Every actor (or class) you place in your level has “properties” that you can change to suit your liking.

We’re going to make this creature ignore you when you test your level.

Once you’ve pressed F4 you should see a window appear that says “Slith properties” at the top of it. (If it says “actor properties” It means you’ve got more than one item selected. Just left click on a blank place anywhere in your map and reselect the Slith). Don’t worry about that great long list of “properties” you can see for a minute, the only one I want you to select is the one near the top called “AI”, just click on the plus sign and you’ll see another list. Click on the one called “Attitude to player” and it will highlight it as well as revealing a dropdown arrow. Click on the arrow and you will see a list of options, choose “ATTITUDE_ignore” and close the properties window down, your monster is now ready! Every actor has a whole bunch of properties like this that you can
manipulate in this way.

3) Now the last thing for you to add for now is the player’s starting position. You can’t test your map without it. With your actor browser, find the class called “Navigation Point” and click on the plus sign next to that. Just over half way down the list is the player start actor. Select that by clicking on it, and in the same way you added the Slith by right clicking, do this for your player start, preferably far away from the Slith (they smell!). You’ll see a little joystick appear! Just like the Slith this is also directional too. You’re nearly there now.

Level Properties

By default Unreal Tournament assumes you are building a DeathMatch level which isn't very good if you want a casual stroll in your new creation. By changing the "level properties" you can tell UT you want to play something else. For the purposes of this tutorial we'll create an Unreal Single Player map because that's the easiest thing for you to walk around in.

To change the level properties all you need to do is right click somewhere on the main screen where the grids are and choose "Level Properties" from the list. You will see a new window pop up in which you should expand the section called "LevelInfo". The part we're interested in is the "DefaultGameType" which is currently empty.

Now you must choose your game type. To do that you need to bring up the Actor Class Browser again (the icon like a chess pawn). From the list, open up "Info", then, "GameInfo", then, "UnrealGameInfo", then left click
on SinglePlayer.

Go back to your level properties, click on the LevelInfo field and choose "use". The singleplayer game option will now appear in that field.

Only one more thing left to do now to test out your map! ...

Rebuilding

This is where Unreal will take what you’ve done and turn it into your level. Left click on the icon on the top menu bar that looks like two slider bars called "Build options". You should see a screen like this:

Click on the button at the bottom of the window that says, “Build”.

The editor will then “rebuild” and for a brief second you’ll see a status bar telling you how its doing (this takes a lot longer when you start building big maps). You’ll notice also that the lighting has now taken effect in your 3d view.

All you need to do now is go to the top menu, choose File and Save Level (or choose the save icon).
Give it any name you choose and then click save. Your level is now ready. Click on the icon that looks like a joystock on the top menu and you’ll find yourself in your level face to face with a slimy slith that isn’t the slightest
bit interested in you (unless you hassle him!).

In the next tutorial, I’ll be showing you how to add more rooms and make them into more interesting shapes and sizes with better texturing (and I’ll probably throw some other useful stuff in too).

E-mail:Ezkeel@nikodemus.co.uk


Beginners Part2

Beginners UnrealED2 Tutorial Part 2

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Contents

1) New Rooms
2) Manipulating vertices
3) Solid Brushes
4) Textures
5) Shortcuts

OK, this time we're going to do some more adventurous stuff with UnealED. In the first part, you learned how to navigate the editor, create a room and add some stuff to it. This time you're going to add more connecting rooms and add some more stuff.

1) New Rooms

First you need to load in the map you made last time (unless moving straight on to this tutorial from the first one). To do that click on file at the top of the editor screen, choose open and then select your map from the browser.

You should see everything as you left it, but your 4 windows will probably have reset to the center of the grid. Make sure that you can see your room in all 4 windows and that nothing in your screen is selected (left click on a blank part of the grid to make sure).

Now, to create a new room you need to use that red brush outline again (the building brush). When nothing else is selected you can move the building brush and do what you like with it. Unless you've been experimenting, the builder brush should be exactly covering the room that you created, so what you need to do in the top left 2D view (viewing from above) is press the Ctrl key down, left click and drag the building brush away from it. In the 2D views you should see the red brush move, and leave behind a brown square which is the outline of the room you've already made.

Still dragging the red brush, move it so that it is exactly 4 squares above it, but still lined up with your other room like this:

Now, you don't want to see the same old boring cube for a room do you? No way!
Lets change the size so it looks a little different. When you start up UnrealED it always begins with the default size of 256 x 256 x 256 for your cube. To change this, you need to right click on that cube shape which you used to make your brush. This will immediately display a small new window that says "Cube Builder" and you should now see a new window pop up that looks like this:

Change each of the numbers to: Height 512, Width 512 and Breadth 512 and then hit "build" (I chose these numbers because they are multiples of 16 and snap nicely on to the grid). Close the window down and now look at your 2D view. You'll see that the builder brush is twice as big. You can change these dimensions to anything you like (but make sure they're all greater than 1). We don't want our two rooms to overlap, so move the builder brush so that there is about 4 squares gap between them again.

Check out the other two 2D views and you'll probably see that your new box has its floor lower than your previous room. Just move it up in one of those views so that it's on the same level as the other one.

Now choose a texture you like (explained in the previous tutorial) and press the "subtract" icon again (2nd button down on the right of the left-hand toolbar).
Add a light to it the same way as you did in the previous room, rebuild and save it again.

So, how do we connect these two rooms up? We just create another brush like the previous two and make it fit in between them.

This might be tricky, so take your time with this.
There are several ways of doing this, but I only ever use two (just personal preference I suppose). You can either use a calculator to sit and work out how many units big your connecting brush needs to be and then slip it in there (which is the method I used to use a lot). Or you can do it the way that I'm going to show you now which will help you to learn something new.

Right click on the cube again, set the dimensions to 256 x 64 x 64 and hit build. Close the window and look at where the new size brush is on the top left 2D view again. I doubt if this lines up with your two rooms, but we're going to put it there anyway. ?

Click on the "subtract" icon so that it carves your cube out into a room.
Now, here's where the fun starts! Move the red brush out of the way and left click on one of the brown sides of your new room (it should be smaller than the others so zoom in if you need to). The whole brush should turn from brown to yellow, which means you've selected it. Press the Ctrl key down and with the left mouse button still pressed drag the yellow box so that one of the sides exactly touches the sides of one of your other rooms.

Note: If you screw up at any point, there are two useful things for you to know: Firstly, I've found that one of the most useful tools in UnrealED is "undo". Just click on the undo icon to retrace your steps, you'll find it can trace itself all the way back to the last time you rebuilt the level!
Secondly, if you need do away with one of the brushes that you added earlier, simply select it by clicking on it and then hit the delete key on your keyboard and it will vanish from your 2D views (it won't be removed from your 3D view until you rebuild.) Anyway, back to business ...

Now, if you wanted to, you could select the room that's on its own and drag it down to meet the other end of your new brush. But supposing you don't want to move that room. Lets say we want to actually stretch our new room so that it can touch the other one. Here's how you do it.

2) Manipulating vertices.

You'll notice that each corner of your cube has a small dot on it. That's a vertex, and we can move these to change the shape of the room. To move them you need to click on the vertex you want to move so that it turns into a small red star, then hold down the Alt key. With the Alt key held down, and the left mouse key pressed, you can drag this point where you like, so drag it to meet up with the side of the other room. Make sure the line is dead straight or it might give you trouble later. You need to do this with each of the 4 points from that edge. Check it out in all the 2D views to make sure that you have lined it all up nicely. You might have noticed that nothing much has happened in the 3D view, that's because that view is limited as to what it can track.

You may find that you are having trouble getting the vertices to go where you want ! If so, there are things that you can do stop you from swearing at your PC. You probably need to change the "grid size". Your vertex will only feel comfortable if it fits snugly onto the corner of one of your grey grid squares, so to be able to do that, you need to make them smaller. To do that, just right click somewhere on one of the 2D views in an empty part of the grid and choose "grid", then choose a smaller number like 4 from the drop down menu.

Once you're happy with how it looks (you should have three areas all joined up), you can press F8 and rebuild your level. Once that's done, you should see it in all its glory on the 3d view too. (Remember to save it after rebuilding).

3) Solid brushes.

Well, now you've got two really interesting rooms connected by another really interesting corridor! Lets add a solid clock in the middle of the large room.
This time we'll use something different to a cube. Underneath the cube shape is a cylinder shape. Right click the cylinder shape and set the height to 128 and the outer radius to 64. Click on build and your red brush will turn into a cylindrical octagon ! Position it somewhere inside your large room (preferably aligned with the floor) and choose a texture you like from the right hand menu. This time instead of "subtracting" this brush to make a hole, we're going to "add" the brush to make a solid object.
In the tool bar on the left, click on the icon next to the "subtract" icon called "Add". You should see the cylinder appear in your 3d view window. Voila ! As before rebuild (F8) and Save (you really need to get into the habit of doing that).
Experiment with some of the different shapes and see what you can come up with.
Note: If you add a brush and it overlaps a light that you've added, your lighting will be stifled !

4) Textures.

So far you've learned how to add and subtract brushes, and put items into your room. But what if you want to change the appearance of one of your surfaces?
Left click on the floor of your room in the 3D view and it should look shaded. Now, if you like, you can choose a different texture, and when you click on it, the floor will change to that texture. With the floor still selected press F5 and you should see this ...

You can have plenty of fun with this tool. Try checking a few of the boxes and see what it does when you run the map (remember to rebuild and save).
Here is a brief list of what these functions do (they may not mean much to you now, but you may need to refer back to them later).

Invisible: Makes the surface invisible (useful if you want to make an invisible wall that blocks the player)
Masked: Enables you to use a masked texture (choose the masked category from your texture set to see what I mean)
Translucent: Makes the surface transparent.
Force View Zone: Beats me!
Modulated: Check it out !
Fake Backdrop: Used for Skyboxes (see skybox tutorial)
2-sided: used for a "sheet" brush (see tutorial on ZONES)
U-pan and V-pan: Makes your texture scroll horizontally and vertically (useful for water or sky)
Hi and Lo Shadow detail: Different ways of responding to lights.
No Smooth: No idea
Special Poly: Not sure, may have something to do with parots.
Small Wavy: This should make you surface wiggle about like rippling water.
Dirty shadows: This will obscure your surface, making it appear gloomier.
Bright Corners: Sometimes, you have a tiny brush cut out of a surface that won't respond to lights, use this to get results !
Special lit: When your light actor is also set to special lit, your surface will only respond to that as its light source.
No Bounds Reject: Duh, wha? come again? ...
Unlit: The surface will look just as it does in your browser, and doesn't respond to lights. Good for neon signs or control panels.
Portal: uses your surface to be a side of a "zone"
Mirror: Turns your surface into a reflective surface (click transparent as well, and you get a shiny floor !)

You'll also notice the other tabs at the top of the window. Again, feel free to experiment, but here's what they do:

Rotation: Enables you to rotate your surface, try it.

Pan: You can shift your texture sideways or up and down to match textures that are next to it. Just press the squares and you'll see the texture start to move by the amount in the check boxes (1,4,16 and 64)

Alignment: Another tool to help you get surfaces matching perfectly, you can also do the same by right clicking on your surface and choose "align textures"

Scale: This is useful. By choosing a ratio in the "simple" scaling box, you can enlarge or reduce the texture on your surface.

Experiment with all these settings, its the best way to learn. :)

That's it ! Have fun and create some monster levels.
I'm pretty sure you now know the basics. To start making more advanced stuff like moving doors, pools of water, and funky lighting you'll have to check out some of my other tutorials.

5) Shortcuts

Before I go, you will find these very useful: a selection of short cut keys that will make things much easier and quicker for you ....
I tend to use Ctrl-W and Shift-B the most, but there are some really useful key combos here ...

F1 : Help.
F4 : Actor properties.
F5 : Surface properties.
F6 : Level properties.
F7 : Compile changed scripts.
F8 : Rebuilder.
B : Toggle brush visibility in the current viewport.
H : Toggle actor visibility in the current viewport.
P : Toggle player controls or realtime update of the viewport.
Shift-A : Select all actors.
Shift-B : Select all surfaces belonging to the selected surfaces' brushes.
Shift-C : Select adjacent coplanar polygons.
Shift-D : Duplicate selected actors.
Shift-F : Select adjacent floors.
Shift-G : Select surfaces belonging to the selected surfaces' groups.
Shift-I : Select surfaces with items matching the selected surfaces' items.
Shift-J : Select all adjacent surfaces(flood-fill).
Shift-L : Look ahead in the current viewport (no pitch or roll).
Shift-M : Memorize selected surfaces.
Shift-N : Select none.
Shift-O : Select surfaces from intersection of selected surfaces and memory.
Shift-P : Select all surfaces.
Shift-Q : Reverse the set of selected surfaces.
Shift-R : Recall memorized surface selection.
Shift-T : Select all surfaces which use the current texture.
Shift-U : Select union of selected surfaces and memorized surfaces.
Shift-W : Select adjacent wall surfaces (flood-fill).
Shift-X : Select exclusive or of selected surfaces and memorized surfaces.
Shift-Y : Select adjacent slanted surfaces.
Shift-Z : Select none.
Ctrl-A : Add brush to world.
Ctrl-B : Load brush.
Ctrl-C : Copy.
Ctrl-D : Deintersect brush with world.
Ctrl-E : Save as.
Ctrl-L : Save level.
Ctrl-O : Load level.
Ctrl-P : Play level.
Ctrl-N : Intersect brush with world.
Ctrl-R : Redo.
Ctrl-S : Subtract brush from world.
Ctrl-V : Paste.
Ctrl-W : Duplicate.
Ctrl-X : Cut.
Ctrl-Z : Undo.
Delete : Delete selected actors.
1, 2, 3 : Slow, medium, and fast movement speed.

EZkeel@nikodemus.demon.co.uk


Building a Map

Creating a Map

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Contents

1) Planning
2) Brushes and Textures
3) Zones
4) Additions
5) Other points

Introduction
This tutorial assumes that users are familiar with the very basic functions of the Unreal Editor such as adding and subtracting brushes, rotating and positioning actors and brushes, rebuilding, bringing up object properties etc. This is not the definitive way to make a level for Unreal, its just the way I do it. If you like my maps and want to know how I go about creating them, then this tutorial is a brief summary to show you.

Most of this doesn't go in to great detail so if you need to know more specifically how to do one of these things, then there may be a tutorial available for that particular activity (I've put the links in this document).

1) Planning
Have an idea in you head what you want. Try and visualize it first and have a rough idea of how you will achieve it. I usually have some crazy idea of what I want to do and then find that it’s not as easy as I though it might be! Always check that you can actually do something before you attempt it. I learned most of what I know through studying the maps that came with Unreal. Build the basic room areas with all the connecting corridors. Don't add any movers just yet. Try and make your rooms varied in shape. Straight cube rooms will become boring after a short while. Overlapping cubes can give a good effect. Overlapping and then rotating them can also look interesting. You can use the cylinder or cones too. Just try and keep them a varied shape

You should also use the 2D shape editor - see the tutorial.

Changing the grid size is often necessary. Just right click in any of the grid perspectives and choose "change grid size". Its set to 16 by default but changing it to a smaller number helps you line things up better. I usually keep the basic rooms at a multiple of 16 in its size. Such as 256 x 512 x 512. This makes it a lot easier when you line up your textures, but its not absolutely necessary. If you are making a large map, it may be easier to build lots of separate UNR files and then add them all together at the end to make the final map. Its often the rebuilding that takes time, and the smaller the map you are making, the less time it takes to rebuild. Do this by using file "export level" and file "import level"

2) Brushes and Textures
Make sure you align your textures. You can do this in the "surface properties" by clicking on a surface and pressing F5. Click on the tab called "pan" and from there you can fine tune your texture by clicking on the 4 small squares to move it. The tab called "scale" will also help you to get your textures the right size too.

Also, by right clicking on more than one surface and right clicking, you have a variety of menu options available that can line them up for you. When you do add brushes, actors or anything in your world, its a useful trick to "group" things. For example, you may have a level with 5 rooms. Click on one of the rooms and also everything else in the room (keeping the CTRL key down when you're clicking will keep all your selections as you click on each one).

Now press F4 and this will bring up the "properties" menu. At the top of the menu it should say something like "27 selected". If you now click on the property called "object" you will see a field called "Group". Type anything in here you like and everything you have selected will be assigned to that name. Now, every time you right click on something from that group and choose "select all" it will pick everything belong to that group. That's really useful for things like dimming the lights down in a whole area. Remember CTRL-W, I use it more than most other functions. This is a really useful command. It copies whatever you've highlighted (except for its event tag I think). So, if you've created a room, and you want another one that looks very similar nearby, just select it all (remember you can group things), and press CTRL-W. Then move the highlighted copy wherever you like and rebuild. Its neat, quick and saves a lot of work!

Create a separate box say 2048 x 2048 off to the side of your map somewhere. Here you will create individual items such as decorations and movers. You can then intersect them and add them to your world.

The tutorial on MOVERS will help you with this.

Rebuild and save (very) often. This is a must.
If you don't you won't be able to keep up with how you're progressing and the 3d screen can't either. The larger the map, the longer it will take, but don't be put off, it'll save you a lot of work later. The only drawback with rebuilding is that you can't "undo" back past the rebuild.

Believe me.....
When you reach a point where you're happy with what you've made so far, back it up as a different file name. This is useful if you change something and cant get it back as it was. In outside areas use the floor lofters. This is essential for creating good cliffscapes and bumpy ground. The alternative is lots of scew shaped polygons which will often freak your editor and slow it down an awful lot.

Don't be put off by it being called "experimental" it works fine and your computer won't explode. (Well, you might get the odd crash here and there.) Use the 2D shape editor to help you with archways and fiddly decorations. Again, don't be afraid of it saying "experimental", it works just fine.

See the tutorial on 2D Shape editor. Note: Close this application down before saving your level otherwise it crashes and sends you out to drown in more coffee!

3) Zoned areas
Add zones such as water and lava.
Zones are fiddly things, but again, they are essential to make a good level and can make the level run more efficiently.

See the tutorial on ZONES.

Create a skybox so that outside areas can look realistic.
Even if there isn’t an outside area, it always adds atmosphere to have some windows or sky lights that reveal the outside world.

See the skybox tutorial.

4) What to add
Add lights to your world, but remember that lights shouldn't usually come from nowhere, there is usually a lamp or something that will generate light (Some of the lamps included in the decorations class give off their own light) Be careful with lights. If you add too many lights (especially dynamic lights) it will drastically slow down the action.

See the separate tutorial for LIGHTING.

Add a player start. If you want to test your level, that's essential. Go to classes on your right hand tool bar and choose "Navigation points". Under that section you will find an actor called "player start", just add this where you please in your map. These are directional, so you can click on it and point it where you like. (select it in the map, so the arrow appears, then press down ALT and left click your mouse. Moving the mouse will then turn your actor)

Add pawns and pathnodes.
See the tutorial on CREATURES over at Unreal Technology.

Add your triggers, dispatchers, counter, round robins to script events.
See the TRIGGERS tutorial.

Add inventory items. This can be translators (should be placed at the beginning of the level near the player start), ammo, health and other useful ditties. You'll find these under the "classes" section on the right hand tool bar under "inventory". Items should be carefully balanced with the amount of monsters, how you work this out can have a big impact on game play.

Add Ambient sounds
See the tutorial on SOUNDS.

Add music
See the tutorial on MUSIC.

Add translator events to aid the story if you're making a single player map.
Suspense and build up add spice to your level.
See the tutorial on TRIGGERS again.

Add a teleporter to take you to another level.
Players like to know when they've finished!
See the tutorial on TELEPORTERS (this will also include warpzones/portals)

5) Other points to remember
Check out the 3D view window and you will notice a small icon that looks like a joystick in its menu bar. When pressed, it enables you to not only see the environment as it stands, but see the moving textures and hear the ambient sounds.

Test your level in its different progressive states. This is also important. You don't want to get so far in your building and then find that something just doesn't work properly that effects a million other things!

Add your level properties. Here you can tell Unreal what your level is called, which game type to use, who made it, what music to use and various other details. Just right click in one of the windows and choose "level properties". Under the section called "Level info" you can tell it your name and the title of your level.

Under the property called "Audio" you can give the level its own music.
See the MUSIC tutorial.

Under "default game type" you can tell Unreal what kind of level this will be. Do this by selecting "info" from the classes menu. Then click on "Game info", then on "Unreal Game info" and then choose your game type. (VRikersGame is where you start with 12 health, staring at the ceiling)

Hope these help you in your level building :)

EZkeel
(Simon West-Bulford)


Learning to use the Editor

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers :

The Basics of UnrealED

Forward:

Basic movement and slightly more advanced movement
throughout the editor.

Content (or whatever):

The most basic thing you need to know about the editor,
is how to move around. Believe me this annoyed the heck out of me until I figured
it out.
To move around (forward, backward and turn around) you must use the left
mouse button (hold and move around). To look around(any direction) without moving, you must use the right mouse button (hold
and move around). And this is the most tricky one. Well for me anyway. It took me a while to
figure this one out and believe me , IT HELPS!!!! Hold down both mouse buttons at the same time to move up , down ,strafe
left and strafe right (try to make a map without out being able to look from inside
your rooms and you'll know how I felt (besides stupid!)).

Moving objects:

Objects are pretty much the same. While in the 3d view, to move your builder brush (red box) , select your brush (left click on it, it will show up bright
red) , then hold down control and use the left and right buttons (not at the same time)
to move your object forward , backward and sideways. To move up and down , once again hold both mouse buttons down.
Note: When moving an object (while holding control and whichever mouse button) the object will only move when you move the mouse to the left or right (the logic escapes me when moving something up or down).

2d Views:

The 2d views are the easiest to use when trying to position an object. These are very handy when trying to place an object right on the ground
or a wall etc. So try to use these if you get stuck (or to prevent you getting stuck).

Movement in 2d Views: Left Click + Drag.

Object movement in 2d Views: Hold control and move with left mouse button.

Advanced object movement in 2d Views: This becomes REALLY HELPFUL.
Highlight an object (click on it) and then hold down control and the right
mouse button then drag in a direction. The object will begin to rotate!!! You can position it however
you want if you use all the 2d views.
Top view: Rotates it.
Side view: Flips it.
Front View: Rolls it.

Undo <-> Redo : Very handy for mistakes and slip ups. These are the two arrows up
the top.

About this tute: I thought it would be helpful.

About the tutes: I decided to write some tutes because of the fact that nearly every tute on the net has been written for UEd1 and that really pisses me off..... sorry about that , but that's the truth. I apologize for the use of so many brackets , but that's just the way I "write".

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Creating Your First Room

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers :

Creating Your First Room

Forward:

This is the second tutorial in the beginners section and I hope it helps you out!

Content (or whatever):

OK so you've decided that you want to create a map for
Unreal Tournament. Well you've taken the first step, ARRRGGHHH, I'm making this
sound like you want to quit smoking or something. Sorry.
The first thing you need to do is make sure you have UnrealEd 2.0, to get it just download the latest patch for Unreal Tournament(436), because it's provided in there. Anyway, open up the editor (it'll be in your UT/System folder) and get familiar with the moving around process
(I suggest that you read the first tutorial on the Basics of Movement first).
I also suggest that you run the Editor on 1024* by 768* screen resolution.

Starting:

When you are ready to start , right click on the build cube button:

and you will then see the properties of the cube you're going to build. For this tute lets leave it at: 256H , 256W and 256B (length is also known as breadth) because that's just a good small room.
Now you will see a red box on your screen. This box is your "Builder Brush". The Builder brush is always there, but doesn't actually do anything until you add or subtract it to/from your world. Now we want make our room, so : Click on the Subtract button :

Note: This is the way i see it : Lets say you are God and you get a big dob of crap, to build your world with. When you are putting a shape into nothing ( straight into the world (empty space)) you must press subtract ; it's like your are taking some of that crap away from the pile , so that you can add it to your world. Then when you want to put walls etc. into your Room (Room=hollowed out crap) you must press the Add button, because you're putting some of the crap back (it's just like a sculptor , he puts back all the clay he doesn't use).So in the end , you'll probably end up with just as much crap as you started with , and that is why people just keep on creating maps, ( they're just trying to get rid of all their crap.)

Now you have your first room!!!
"But the walls have a shoddy paint job" , I hear you say. Not to worry. This is where
it is your turn to make the room look how you want them to. We need to change the textures in your room. Textures determine what the walls, floor and ceiling look like, they are like Paint or Wallpaper.
Click on the Texture browser icon (the second last one - looks like a landscape painting).

The different browsers

Click on open package (above where it says "Botpack") and select : UTtech2 (this is just an example, you can select another one if you want, but this one is good for this tutorial).
Now click where it says base, scroll down and select walls. Pick out a nice wall from here and click on it
(only once so it is kinda highlighted). Then right click your walls that you want to
put it on (if you hold control and then left click, you can select more than one wall at a time), and select "apply texture".Tada! Now your wall looks different!
Do the same with the Floor and Ceiling (but not with wall textures!).
Now press F8 and press the confirmation button when then window shows up (but if the window doesn't show up, just click on this: partial and full rebuilding options). This button is the Rebuild button. You must press it after every major thing you do, such as moving a room or adding/moving lights. To make the changes show up properly. "ARRGGGHHHH" , I here you say! My room is gone! Well actually , you just cant see it because it has no lights in it.
Well lets change that. Just above your 3dView you will see a little green cube , with
other cubes next to it. Click on the one on the left (textured) of the green one.

different views
This will now become green. Ahhhh, I here you say as your room re-appears.
The cube on the right of the now green one is "Dynamic Lighting". We will use this after we put some lights in. Anyway , right click any where in your room and select "Add Light Here". You should
only put about two in this room since it's not very big (but space them out, and make sure they
aren't going through the floor or something, make sure that they are in the room).
Now rebuild again ( F8 or partial and full rebuilding options) .Then click on "dynamic lighting" (on the right of the green
Cube). Ahhhhh , oooooh .It's pretty isn't it? Now we are finished with our room!

But how are you going to play it I here you say. You have to put in player-starts :
Click on the "Actor classes Browser" it looks like a pawn. Now in the browser ,
expand "Navigation Point", then left click on "PlayerStart". Now go back to your map and Right click any where on the ground and select "Add PlayerStart Here" (leave it where it is created, if you want to move it, use the 2d Top view, just make sure it's not going through the floor or a wall).
If you want a gun in your level , go back to the actor classes browser and select:
Inventory, Weapon, Tournament Weapon and then whichever one you want. Add
it to your level just like you did the playerstart (right-click then select add "xx" here).
Then go to Inventory, Pickup, Ammo, Tournament ammo and select the appropriate
One if you want any of them. Add it the same way.

Note before you play: DO NOT USE BOTS IN THIS LEVEL. Because you only have
one playerstart , everyone will try to spawn in the same spot , and it will cause everyone to be telefragged.

You are now ready to play your level! Just rebuild , and press on the little Joystick up the top (or press Ctrl P ). If you want to keep it , Save it as " DM- xxxxx" or whatever you want to call it. Just dont forget the "DM" part. This also applies for CTF, DOM and AS, but we wont go into those in the beginners section.

P.S : I am sorry if any of this was complete crap and yes that's including the "Crap Theory".

About this tute: I thought it would be helpful. This is the 2nd edition of this tutorial (it has been revised around 6 months after it was originally made).

About the tutes: I decided to write some tutes because of the fact that nearly every tute on the net has been written for UEd1 and that really pisses me off..... sorry about that , but that's the truth. I apologize for the use of so many brackets , but that's just the way I "write".

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Creating Your Second Room

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers :

This will cover creating a second room and linking the two together.

Forward:

This is the next tutorial in the beginners section and I hope it helps you out! Make sure you've read the first two before you start this one!

Content (or whatever):

Welcome back. I am writing this tutorial more than 6 months after the first two (but i just revised the First room tutorial so it will be similar), i am just telling you this because it means that it might actually make sense. O.k, lets get into it. Open up your 'first room' map if you saved it or still have it open, otherwise, just quickly make a 256x256x256 cube and subtract it. Then add some textures to it. If you don't know how to do this stuff, go back and read the first tutes.

Here is how it should look:

O.k. Going great so far. Now to start the learning. We want to make a second room of equal size, so there's no need to click on the cube, because our builder brush never disappears. See the red boarder around our room in the 3D and 2D views? That's the builder brush. Click on it in the top view (it says the Top and 'T' is highlighted [first 2D view above the 3D one]). If it wasn't already, it will now become highlighted (the builder brush). Move it across two of those square spaces.

Your screen should now look like this:

moved builder brush

Good work. Now Subtract it and texture it how you want it. I haven't added any lights to mine yet, but you might as well do it all at once at the end anyway.

Now right click on the cube button and made it 128hx128wx256b. Click build. Now move the builder brush so that it's perfectly in the middle of the two cubes. Update shot:

room #1 and #2

Do you notice anything wrong? The builder brush (which is going to be our connecting hallway/passage) is floating in the air! Click on it in the Front view and move it down so that it's in line with the bottom of the rooms. Now press the intersect button (under Add). In this case it isn't really necessary, but it's very handy when connecting two things or deleting a section of something. If when you press it and nothing happens, that's a good thing. It means that it was evenly in line with the rooms. If not, just left click on the cube and try again (check the alignment this time).

Now subtract it. Your rooms are now linked! Congratulations! You now know how to link rooms together, which can be done an unlimited amount of times! (there is actually a limit to how big your map can be, but lets not get into that at the moment because you don't have to worry about it since its like 16000 kilometers[but dont quote me on that]).

Now add lights and playerstart(s!) to your level as well as necessary pick-ups etc., rebuild the level

(F8 or [image]) and then save and play!

2 rooms with halway

Your final screen!

(Please ignore the green room. Yours will not look like that, i was just bored.)

About this tute: I thought it would be helpful to anyone who wanted to advance a bit from the last tutorial.

About the tutes: I decided to write some tutes because of the fact that nearly every tute on the net has been written for UEd1 and that really pisses me off..... sorry about that , but that's the truth. I apologize for the use of so many brackets , but that's just the way I "write".

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Adding Brushes

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers:

Adding objects inside your rooms.

Forward:

This tutorial will run you through adding: a nice little building and the infamous 'crate'. *Note* This is a fairly long tutorial, but a very detailed one (i am quite proud of it. 8D [<--that was a face...]It shows that i am getting used to 'writing' these and also getting better at it).

Content:

Well you've made it this far, and that's great. By this time, i hope you've been experimenting a lot on your own with what you've learnt so far, because that is the best way to understand what is going on. Anyway, lets get down to it.

Make a room (768h, 2048w, 2048b). This is a big room, because we are going to be putting a whole bunch of stuff in it. Open up texture package UTTech2. Its rather boring, because it's been used so many times, but it has everything we need for this tutorial. For now, just choose a nice base texture and subtract our room.

Its looking very dull at the moment isn't it? Well, thats what we're going to change.

Now make a cube (384h, 768w, 384b). In the 2d front or side views, move it down so that the bottom is exactly in line with the bottom of the room. Now, go to the top view, hold down the right mouse button and control, then rotate it untill its at a nice angle.

Here is how it should look:

in the corner

Now, select a nice texture for a little house thing and then press the

ADD button ( the add button). Now, right click on the new cube in the 3D view, and select: Select surfaces> Matching Brush. All sides of the cube should now be selected. Now, right click on it again and this time select: Surface Properties. Click on the alignment tab (if nothing happens, click on flags and then alignment). Where it says scaling, enter 1.5 in the first box, then hit apply. This will just make the textures look neater. Your screen should now look something like this:

At the moment, the box serves no purpose, but we're getting to that part. Now we're going to hollow out the box so that it is useful. We want all of the walls to have thickness, so we will now make a cube (352h, 704w, 320b), this way, all of the walls will be 32 units thick...well, they will be soon. Now, move the builder brush down in the front or side 2D view, so that the floor is in line with the other floor. You should see in the top view that it is exactly in the center of the added cube. Now press Subtract (you should know where it is by now, without me having to tell you...). It looks like it has done absolutely nothing, don't worry, you will see soon enough.

Now make a cube (320h, 192w, 32b). Move the builder brush to the front of the cube (side not facing the back walls) and position it off center, since it is going to be our door. Do this in the top view and then in the front or side view, move it to ground level. It should look like this:

position for door

Now press the subtract button and if you hadn't figured it out before, you can now see what we have done. We have made a small house/room with a doorway. This is how it should look now (after texturing [use a scale of about 1.25-1.5 for the walls]):

doorway + textured view

Great work so far! You have learnt quite a lot. Now to some easier things...

Lets make some (ever popular) crates. They are very simple and [can] add a bit of atmosphere to a level. Make a 128³ cube and move it to the ground and away from the house/building thing. Add it (the subtract button is used to add whole rooms to the world and to hollow out other things, you can walk inside a subtracted brush, add is used to build things inside a subtracted room or object, you cannot walk inside an added object, but you can walk on top of it etc, just keep all of this in mind if you are ever not sure which you should be using). Anyway, back to it, add the box and then select surfaces>matching brush on the box. Go to the 'deco' section of UTTech2 and select a box texture. Now go to surface properties and apply a scale of .5. There you have it, a simple crate!

Now, with a combination of some know-how (i used something that i haven't yet taught [2Deditor] woopsie!) and just a little bit of imagination, you can create something to this effect:

About this tute: I was asked to do this and i think it is quite a good subject, because it can explain quite a lot to the UnEDucated. I hope you've learnt a lot from this tutorial, because i've certainly learnt a lot about writing them. I think this is a very important subject to learn and i hope you've had fun doing it!

About the tutes: I decided to write some tutes because of the fact that nearly every tute on the net has been written for UEd1 and that really pisses me off..... sorry about that , but that's the truth. I apologize for the use of so many brackets , but that's just the way I "write".

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Basic map submission

Lesson 1

By: Deathbliss

Deathbliss

Your first room:

Well go ahead and open up UnrealED. In this tutorial you will learn how to create your very first room. Throughout the series of these tutorials you will learn various things from me that I have learned, a few tips and tricks, and by the end of these lessons you will be well on you way to becoming an excellent Unreal Mapper. Unfortunately Unreal is getting misplaced more and more by Unreal Tournament (which I will eventually cover) but you should still find what you need here and a few other places. I'll place some links to what few places I know of soon. For these tutorials I will also provide printer friendly versions along with the maps that go with the lesson all in a convenient download. Keep in mind things may move slowly, and I will still be learning as I teach you. You can e-mail me here.

Back to work...

Okay, so you are faced with a screen that has three squares in the middle that look like little graphs, a square displaying a black void, a column of little buttons on the left side, and a bunch of pictures or words on the right. Here's a breakdown of what everything is:

Note this, as I will be referring to the editor's functions as shown above frequently. RIGHT CLICK on the little square icon. You should see the following box, set everything to what you see below:
Once you've set it CLICK on BUILD. Now you should have a cube sketched out in red lines in the bottom leftmost box - floating in a black void, and in the other boxes you'll the same thing on the gray grid. The top leftmost is the TOP VIEW, as if you were flying over the level. The one right next to it on the right is a view from the side of your level - the SIDE VIEW, the last grid box on the bottom is the view from in front - the FRONT VIEW, and the final area that is a black void is the 3-D VIEW. Unreal's grid default is from what I understand divisible anywhere from units of 1 to units to 256, with the default set at 16. Hence the weird numbers for the box. You can RE-SIZE THE GRID at any time by RIGHT CLICKING on any of the views with the grid in it and selecting GRID, then the size you desire. You'll RE-SIZE THE GRID usually for fine tuning the placement of the various pieces of geometry that you add. This should make it easier to align your level upon the gray lines in your top, side, and front views. What's the final box for? You'll see in a sec. Remember!!! The grid runs in units of 16 by default, but this can be changed as I have stated above.

Okay, another thing you need to know at this time that what you see below, the red brush, this is your "carving tool". Unlike Quake style games and levels that add into the void, Unreal style games and levels subtract from the void. In UnrealED, you are a carpenter designing something from a block of wood. The RED BRUSH is your carving tool.

Well now this RED BRUSH still hasn't become a cube. It's shaped like a cube and ready to carve it, so look over to the right of your screen. See those pictures? If not go up to the word CLASSES and CLICK on the ARROW next to it. Select TEXTURES. Here is where you'll find textures from which you can decorate the various pieces of geometry in your level. However there really isn't anything you can use here yet. Look near the bottom of the texture window and find the LOAD link. You'll be faced with a bunch of .UTX files. The files ending in this extension (UTX) are texture files - also known as TEXTURE PACKAGES. You can use what's provided, make your own, or download someone else's. For now we will use what's here. The files with FX in the filename are not useable for wall texturing. Well, they could be but these files are for things like lens flares, lasers, etc. I'm choosing ANCIENT.UTX. You may choose whatever you desire. Find a texture that you'd want for your walls, and click on it's picture. It should now be surrounded by a greenish box. Go up to the top of the screen, and CLICK TWICE on BRUSH. Go down the list until SUBTRACT is highlighted. CLICK ONCE to subtract the RED BRUSH from the world.

Congratulations! You've just made your very first Unreal level! However, you can't explore it yet, and you may want to do some internal decorating. So go ahead and in the 3-D VIEW select the surfaces you wish to change by LEFT CLICKING on them. You can select multiple surfaces by PRESSING DOWN and HOLDING the CTRL button while LEFT CLICKING with the mouse. I used BASICROK 2 for my walls, ACEILIN 1 for my ceiling, and AZ FLOOR for the floor. If you'll look next to the word ANCIENT in the TEXTURE BROWSER you'll notice 2 arrows pointing away from each other. Click these arrows to select the different texture (UTX) packages you've loaded. You can load as many as you like, and use whatever you want among them. The next lowest set of arrows will take you through the various types of textures in the texture pack currently shown. You can select a wall texture from WALL, a ceiling texture from CEILING, etc. Or you can use a wall texture for the floor. Everything is easily reached and well organized in the TEXTURE BROWSER.

Well, does everything look the way you want? Once it does, go up to the word TEXTURE and then CLICK on the arrow next to it. Highlight the word CLASSES and CLICK ONCE. The TEXTURE BROWSER is located in the same area as the CLASSES BROWSER, and here is where we find something we need, a PLAYER START. In the list, CLICK on the MINUS next to NAVIGATION POINT to expose yet another list. In there you'll see the words PLAYER START. CLICK on them, if a weird box comes up with a bunch of gobbledygook in it (stuff you may not understand) just CLICK on the X at the TOP RIGHT to remove it. Once PLAYER START is highlighted move your cursor inside the texture view. Moving the mouse while CLICKING and HOLDING the left mouse button will move you forward, and the same applies for moving backward. CLICKING and HOLDING the RIGHT mouse button lets you look up and down. CLICKING and HOLDING both mouse buttons elevates your position up or down. These are the basic movements in the 3-D VIEW. Anyhow, look down at the floor where you wish to put the PLAYER START. It must be inside the level you have created. RIGHT CLICK on that point above the floor, select and highlight ADD PLAYER START HERE from the list, CLICK once and a little joystick should have materialized into your level. Zoom in on it in the TOP VIEW by CLICKING and HOLDING the LEFT mouse button, then CLICKING and HOLDING on the RIGHT mouse button. In the TOP, SIDE, and FRONT views this is how you zoom in and out, by following these instructions and DRAGGING the mouse forward or backward. Once you've zoomed in let go of the mouse buttons, click on the joystick to highlight it, and then PRESS and HOLD CTRL. Now CLICK and HOLD the RIGHT mouse button and DRAG your mouse to point the RED ARROW in the direction you wish to face when entering your level.

Almost done! You'll need a light, right? Well in that list you saw when placing the ADD PLAYER START HERE you may have noticed the words ADD LIGHT HERE. Again in the 3-D VIEW follow the same instructions for adding a PLAYER START, only highlight and CLICK on ADD LIGHT HERE. Put up to 4 in your level, and try not to get them too near the walls. I would RIGHT CLICK just away from the corners of your ceiling and place the lights there. Ready? Well here is where you need to do next - REBUILD your level. Do this by PRESSING F8 or going up to the top of the screen clicking on OPTIONS, then selecting and CLICKING on REBUILD. Here's what the REBUILD box looks like, and don't change any values:

This is what my level looks like.

CLICK on REBUILD GEOMETRY, and once it's done rebuilding go up to FILE, click on SAVE, and name your level EXP1. SAVE your level, the click on FILE, select PLAY LEVEL, and CLICK ONCE. Now you'll be transported into the level you just made. Sure, there's nothing much there now but we'll work on that in the next tutorial. You have just gotten further than most people have ever will, and you have just created something of your very own. For me this is my main reason for continuing, and I hope I will be able to get you even further than this. With UnrealED and the Unreal Engine there really aren't any limits at this point in our mapping explorations. The sky's the limit, and we have a helluva lot more we can do. Take a break and come back later for Lesson 2.

Final notes on REBUILDING:

Thanks Tim for pointing this out. Remember that view that started as a black void? Well that view (the 3-D VIEW) does not always show you what you're doing in a level. If you delete a lot of brushes, or add a lot of things and move them around, they may appear to be the same as before you changed them in the 3-D VIEW, so you may feel like it's not working. THIS IS NOT THE CASE!!! The 3-D VIEW only updates after you REBUILD, so remember to RE-BUILD after any big change in your level, and the SAVE accordingly. Once you RE-BUILD your level, everything should look the way it supposed to. This is not a flaw in UnrealED, it's merely the way UnrealED works.


Basic map submission

Lesson 2

By: Deathbliss

Deathbliss

A hallway with windows:

Well part of building levels is exploring, and trying new ideas as you go along. In the spirit of this I will learn with you as we create a hallway with windows. Go ahead and open up the last save of the map you have been working on with me (from lesson 1). CLICK on FILE, and select OPEN LEVEL. From the list select EXP1.UNR (if you saved your level as something different then load that file - it's the level we began in Lesson 1). Wait for your level to load. RIGHT CLICK on the CUBE ICON on the left of the screen. Set everything the same as you see below:

CLICK on build, and align like this:
Well you may want to get the textures you will use ready for your hallway, from the first lesson you should have learned how to load texture packages (UTX files). I am using ANCIENT again, but wait, it's already here! That's right, the textures you use load right up with your map. Cool huh? However I need more textures so I am re-loading ANCIENT because I want a Tomb Raider like feel to my level. I used BASIKROC2 for the walls and ceiling, and AZ-FLOOR for the floor. Now you need to press the DE-SELECT ALL button, this button resides on the left of the screen in the toolbar and is a picture of a circle with a line through it. Right there under ALL (which is SELECT ALL by the way). Once you DE-SELECTED everything in your level click on the texture you wish to use for the walls of your hallway. Now SUBTRACT the RED BRUSH (head up to the top of the screen, CLICK on BRUSH, then SUBTRACT) and the RED BRUSH carves you a hallway. In the 3-D VIEW you should be able to see it. Go ahead and press F8 to REBUILD (or go to OPTIONS then REBUILD) and once it's done SAVE your level. Remember to SAVE often! UnrealED is BETA and unsupported, so if it crashes you could loose everything you've done.

Well as I said I am going for a certain feel, so I put a FLASHLIGHT in my level, I RIGHT CLICKED just above the floor just outside the entrance to the hallway and placed my FLASHLIGHT there. To put a FLASHLIGHT into your level click on that little arrow pointing down in the top right corner of your screen next to the word TEXTURES, and select CLASSES from the list. Click on the minus next to INVENTORY, then the minus next to PICKUP, finally select FLASHLIGHT. If you click the minus there you'll also find SEARCHLIGHT, but FLASHLIGHT will do for now. RIGHT CLICK in your 3-D VIEW anywhere you desire above the floor to add the FLASHLIGHT to the level. What was the point to all this you ask? Well you've just learned that there are a LOT of items in the CLASSES BROWSER and this process is the same you'll follow for weapons, ammo, health, power ups, etc. You can even find decorations to put into your level!

Ok, so now the windows. Well I've never done this - honest. However I am a little familiar with SHEETS and I think this will help us. There are two approaches to what we're about to do:

1. Make a box that you can design your geometry in. This box will be deleted after your level is complete.
2. Ride it out by the seat of your pants, and design your geometry wherever you find space!

I use the second option. Well our hallway is 128 Unreal Units high. So my windows will be the following size:

I moved the RED BRUSH (which is now shaped like the window I'm about to create) into the biggest room and will perform surgery there. Find a texture you like, DE-SELECT all then select this texture. SUBTRACT from the world. What's this? Not seeing anything? Find the UNDO button on the left side of the screen in the toolbar and CLICK it. You cannot SUBTRACT inside a SUBTRACTED area. Can't be done to my knowledge. You've cut out a hole in your block of wood, and you're trying to cut a hole into a hole. Nothing subtracted from nothing equals nothing. Go up to BRUSH, select and CLICK on ADD and you should see what will become the outer frame for your window. I am using a TRIM texture - TILEMOS 3. The reason why is that you'll have a design in the frame after you're finished. Currently what I got was too big, so I RIGHT CLICKED one of my window frames surfaces, went up the list to SELECT and then MATCHING TEXTURE. Now the whole window frame is highlighted with these annoying blue dots. I RIGHT CLICKED again and selected SURFACE PROPERTIES, then I CLICKED on the SCALE tab, and under simple scaling I selected 0.25. Here is what I have:
Okay, so we have an added brush in a subtracted brush. To hollow out the center of this added brush we need to do what? That's right - we SUBTRACT it. so build another cube precisely 16 Unreal Units smaller than the cube above. My measurements are:
My goal is to fit the interior of the window exactly to the cube design on the window frame. Select the same texture as you used for the window frame. Check to be sure that in all views the RED BRUSH is exactly in the center of the window frame, then SUBTRACT the RED BRUSH. We should have a hollow space inside a frame. This is my completed window frame:
Now you may desire to RIGHT CLICK on one of the surfaces inside the frame, and then set the size to the same size as the outer frame. Remember there is another box inside of the outer one, and it leaves a few surfaces the default size of 1.0. Okay, so all that's left is to place these in the levels. We want them along the outer walls of the hallway. You may want to go to the SIDE VIEW and select both boxes that make up your window (select by clicking on one of the boxes, and then PRESSING and HOLDING CTRL as you click on the other one), go to BRUSH PROPERTIES, then OBJECT, then CLICK in the box next to GROUP. Name them something (I've called mine HALL_WINDOW). Now when you press SELECT ALL later you'll just select the windows provided one of the windows was highlighted (selected) at the time. PRESS and HOLD CTRL to move the window where you want it, try to keep it above the floor and below the ceiling. Now RIGHT CLICK and select DUPLICATE from the list. Position the new window frame wherever you want. do this up to 6 times, I've done it only 4, until your hallway has windows inside along the walls, like this (it doesn't matter if they stick out):
REBUILD (F8) and save your level as EXP2. Now we need to build sheets that will serve as our windows. In the next tutorial we will cover skyboxes so you can see something out of them, but for now well just get them ready. Find this icon in the Toolbar and RIGHT CLICK on it:
This is the BUILD A SHEET ICON. set it to the same values seen above. Click on BUILD, and your RED BRUSH has become our window shape. Center this perfectly in one of your frames, and once you're sure it's aligned go up to BRUSHES, then ADD SPECIAL. Set as below:
When you've set it, DE-SELECT ALL and open up the ShaneDay texture package. Highlight DAYSKY 8 then CLICK on ADD SPECIAL. Once all your windows are set RIGHT CLICK on this blue texture in the 3-D VIEW, select SURFACE PROPERTIES from the list, and click in the boxes UNLIT and FAKE BACKDROP so that they have a check mark next to them. CLOSE the SURFACE PROPERTIES window and any other extra windows open, REBUILD (F8), save, and then try it out. Here's how mine turned out:
If you click on MODE just above the 3-D VIEW you'll get a list of various types of ways to see your level. Select TEXTURES from the list to get an idea of what your hallway looks like. You'll soon see something in those windows, as in the next tutorial we'll design a skybox and discuss ZONES. For now just get a feel for your level, where it's going, and think about how far you've come. SHEETS can be one of the hardest things to learn, and all this aligning can get tedious. But you should be starting to see what can be accomplished with a little sweat and hard work, and things are only going to get better from here on out. I for one am happy with the way this turned out. No unexpected flaws except when I tried one-sided sheets that didn't work on one side of my level. Hopefully we'll avoid nasty headaches. I like the feel of my level, and of course I'm curious about yours. You can e-mail me anytime you need help, and if things aren't working out for you send me your maps and we'll work on them. If you wish to share your work you can e-mail me your maps as well. Everything here in the tutorials is now downloadable for your convenience. Just follow the UnrealED Exordium Main link below. In the end just try to have fun creating, you can do whatever you want and here's a good place to start. See you in the next lesson!


Basic map submission

Lesson 3

By: Deathbliss

Deathbliss

A skybox and an introduction to zones:

In the last lesson we made a hallway with windows, the links to which can be found below. We want to see something out of those windows, right? Well...

In UnrealED levels are made with zones. You want a pool to swim in? That's a WATER ZONE. You want a portal? That's a ZONE PORTAL. You want a skybox? That's a SKY ZONE, and on and on it goes for fog, clouds, and a few more I think. Unlike Quake style editors where you could just put a cloudy texture on the ceiling and "presto!" instant sky (a flaw I think that UnrealED don't work that way) UnrealED and Unreal levels need the clouds in their own little box, not touching anything else. A strength in UnrealED is that despite the extra work, I must admit the clouds look a helluva lot better. You see all of this through a camera like thingy called a SKYZONEINFO. So to start open up the last save of the map you have been working on with me (lesson 2) then RIGHT CLICK on the BUILD A CUBE button (you should know where it is by now...) and set the values the same as below: CLICK on BUILD to make your "carving tool" (the RED BRUSH) the shape that your skybox will be. Now here is where I may be fatally flawed. In other tutorials they all have different ways of doing this but I have discovered a few things:

1. The lengthier and wider the skybox the less chance of seeing the walls of the skybox.
2. You don't want to see the walls because it's noticeable that there is a wall there when you are looking up at the sky.
3. The shorter the height the better because it's easier to hide the walls with the help of the extra length and width.

For an example try sometime opening the file NyLeve.unr. - not now, but later. This is the second level you come to in Unreal, Nyleve's Falls. It's a good place to see and understand skyboxes a little better. You can also download my level "Sniper Heaven" from UnrealED Exordium (link below) to get a better idea of what I want when I look at the sky.

Anyhow if this works out right you won't have to see what I mean. PRESS and HOLD CTRL when the RED BRUSH is highlighted, and move it away from any other area of your level by DRAGGING with the LEFT MOUSE button. Position like so: Now go to the TEXTURE PACK SHANEDAY and if you followed me in the last tutorial that blue texture (DAYSKY 8) should be there. DE-SELECT all then CLICK on that texture. Go up to BRUSH, then SUBTRACT your skybox from the world. The walls and ceiling should have UNLIT checked in their SURFACE PROPERTIES. Now you need to load a ground texture, I am using the TEXTURE PACK GENEARTH and the texture MGRASS 7. You may use whatever suits you. Now here is where my main flaw may lie. Mountains. You build sheets that will have the mountain texture on them, and they are supposed to fit each other as you set them. I can't get them to, still the persons who made Nyleve's falls knew how. So I'm cheating, and we'll use their box since I can't seem to get this mountain trash right. SAVE your level and open up NyLeve.unr. By pressing CTRL the same time you select stuff you can select multiple items. Do this on the following: Once you have all the stuff pictured selected go up to EDIT then COPY. Then go to OPEN and open up EXP3.UNR. Finally go up to EDIT, then PASTE. Wait a moment, find the newly pasted mountains, and position them like so: Now before you get too pissed off at me and call me a hack consider this, your mountains could have been textured differently if you had done it yourself but if done right they'd look like this. I'm certain there's only one right way, yes I haven't found it and no one is giving the information I need out in their skybox tutorials. I will of course redo this at a later date if I manage to find my own way. I will also post the info here. If it'll make you feel any better re-texture the mountains any way you want but be forewarned, they won't look right. While doing this tutorial I experimented with many different positions and none looked right. I'll be e-mailing a few folks about this but for now this will serve our purpose. From here on out it's all original, I guarantee! REBUILD (F8) and SAVE. Open up the CLASSES BROWSER (go up to the word TEXTURES and CLICK on the arrow, select CLASSES from the list). Click on the minus next to INFO, then from the list click on the minus next to ZONE INFO, finally click on SKYZONEINFO. In the 3-D VIEW add SKYZONEINFO right smack dab in the middle of the mountain box - align as necessary. I've placed mine right in the center, and halfway below the top of the mountain box. You'll be free to move the SKYZONEINFO wherever you want, however it must be in the skybox. The SKYZONEINFO is a camera, your view of the sky and surrounding terrain will be affect by it.

Now RIGHT CLICK on the BUILD A SHEET button. Set it the same as your skybox, 2048, 2048 - make sure Floor/Ceiling has a dot next to it. BUILD it and position it so that it is aligned EXACTLY with your skybox. Put it right above the mountain sheets, or one grid below (like me). See below: DE-SELECT all, then open up the texture package GENFLUID.UTX (if your still in the CLASSES BROWSER get back to the TEXTURE BROWSER). In there there is a bunch of SKY TEXTURES - select one you like (I decided to use SKYTST 8). Now go up to brush, then ADD SPECIAL. Set like so: I went into SURFACE PROPERTIES, and under SCALE-SIMPLE SCALING I set the size to 4.0. Feel free to experiment until you get something that you like. Now move the RED BRUSH up a little, between your first cloud sheet and the ceiling - about halfway between them (I moved mine 5 grid units up). DE-SELECT all and find another cloud texture you like, or use the same one. Once your done scale it the way you like. Use the same settings above when adding it. Now go into the SURFACE PROPERTIES of each cloud sheet and under EFFECTS check of either UPAN, VPAN or both - this is how your sky moves. To adjust the speed of your sky RIGHT CLICK on the SKYZONEINFO, CLICK on the minus next to ZONELIGHT and set the TEXUPAN and TEXVPAN speeds to taste (I am trying 0.050000 on both). Now open up the CLASSES BROWSER again. Go through all the steps that got you to SKYZONEINFO, and this time click on CLOUDZONE. Place this in between the cloud sheets, right in the center of everything. It must not be outside of either of the cloud sheets. REBUILD (F8) and SAVE. If everything got dark in the 3-D VIEW CLICK on MODE, and select TEXTURES from the list.

Now build a sheet to these dimensions 128x128 and stick BELOW the lowest cloud sheet and ABOVE the SKYZONEINFO. Open up the texture pack GENFX.UTX, under FLARE textures find one you like (it will be your sun) DE-SELECT all and then go up to BRUSH and ADD SPECIAL. Set it like the following: Select the texture you'll use (I used FLARE 4) and be sure to re-size it to 2.0. Some of these don't work well for a sun, and you can see the faint ghostly outline of the square they're made of. The one I use doesn't, but my other attempts did. If the texture is not aligned - centered on the sheet - then RIGHT CLICK on the sun, go into SURFACE PROPERTIES, and select the tab PAN. Use the four small buttons to align your texture. This step will come in handy as you do more advanced things later. Finally locate this button in the toolbar: Once you've moved your RED BRUSH out of the way and selected your sunsheet PRESS this button (it's ROTATE BRUSH) then in the SIDE VIEW PRESS and HOLD CTRL and DRAG with the RIGHT MOUSE button until your sunsheet is slanted. Do this again in the TOP VIEW as you may want to turn it a little - following the same steps, until you have something like this: What are those lights for? Why they're my SUN lights, so you can feel like your looking at a sun in the level. Add up to 7 lights and position them any way you desire around your sunsheet and in front of it (not behind it) but try to stay in the mountain box while doing so. Once they're in select each one and then RIGHT CLICK on one of them. Under OBJECT set the GROUP to Sunlights (or your own clever name). Under LIGHT COLOR set the three options (from top to bottom) to 150, 0, and 250. You can adjust this later if you wish. REBUILD, and try DYNAMIC LIGHTING under MODE in the 3-D VIEW to see what it looks like. One more step - RIGHT CLICK on SKYZONEINFO and under DISPLAY set the AMBIENT BRIGHTNESS to 255. Under ZONELIGHT do the same. Set the same settings the same way by RIGHT CLICKING on the CLOUD ZONE when you're through.

Have you seen the term ACTOR yet? ACTORS are many things in UnrealED and these zone thingys are one of them, Lights are another. When you select 2 dissimilar ACTORS in UnrealED it gives you the option of ACTOR PROPERTIES. So if for instance you wanted your sun and it's lights to be one total group you could do that. Something to remember...

NOTE:

To drag an item PRESS and HOLD SHIFT or CTRL and drag with the RIGHT MOUSE to move the items. PRESSING CTRL just moves the item, while PRESSING SHIFT will move the item and your view.

Well REBUILD your level and SAVE it as EXP4.UNR. Give it a test run. Follow these instructions to adjust things the way you like. With skyboxes you need to experiment to get anywhere, and this is pretty much as far as I've ever gotten with them. If you have any questions or tips to share - e-mail me.

You're doing well, you've made it this far through these somewhat technical and difficult discussions. When you enter your level you may notice (as I did) that not only do the windows show something, but that the light from them lights up your hallway. May not need that flashlight after all - huh? In the next tutorial I will learn with you as we create our (yes mine too) very first TELEPORTER, we'll discuss zones some more, and I'll show you how to build a pool. Yes, there will be something at the end of that hallway very soon...


Basic map submission

Lesson 4

By: Deathbliss

Deathbliss

More on zones - Portals, TELEPORTERS, and Water:

UPDATE!!!

I have truncated the original tutorial that taught you how to build a portal. Mine seems to have degraded to the point of uselessness in most cases. So I am giving up on PORTALS for now until I get some help from the various people I have e-mailed on the subject. I will be removing the PORTALS from the example map and will focus on TELEPORTERS instead. I will still explain the basics of both, and the original pool instructions will remain mostly unchanged. Sorry for any inconvenience - now let's get to work:

Well in this lesson we'll cover a little more on zones, build a room with a pool, and design a TELEPORTER. I'm REALLY digging Marilyn Manson right now... "...break the speed of pain...". Excuse me, forgot we're doing serious work here. Ok, from here on out I'm not going to take you through the mouse clicks and buttons as much. I noticed 2 shortcomings in my tutorials so far (maybe 3) and they are the following:

1. I didn't explain very well about the saving process and why EXP1.UNR, EXP2.UNR, etc.
2. If you're a beginner you still don't know squat about the TOOLBAR from me.
3. Too technical???

So both here and on UnrealED Exordium's main page I'll be placing links to a tutorial on another site that explains the TOOLBAR pretty well with pictures and all. I'll make my own later for quick reference somewhere. Go there now if your curious, and if your computer is strong enough minimize that window so you can bring it up whenever you desire. Well how was your Christmas? Mine sucked worse than a big friggin black hole. That and adding a PORTAL to the example map was a big, wet flop. But I have Unreal Tournament now and will soon post lessons for UnrealED 2.0. Look for them in the near future if I don't just quit. TELEPORTERS seem to be easy from what I've read, and you can not only use them to switch between rooms but also between levels as well! I'll be designing something fancy to put mine in (because they are by default invisible), and still try to keep with the original "Tomb raider Esque" theme. Bear with me ok?

First off you need to open up the last save of the map you have been working on with me (lesson 3). Then RE-SIZE the grid to 2, this was covered in Lesson 1 and I think is also in Lesson 5. If you're having trouble feel free to e-mail me. Move the RED BRUSH to either your "builder room" (if you're using one) or the First Room - where I am building mine. To make it easy I just highlighted the RED BRUSH and RIGHT CLICKED on it, then selected RESET/RESET ALL POSITIONING - I recommend you do this as well, and you'll see why in a moment. Now load up a texture pack you want - I'm using ANCIENT.UTX. DE-SELECT ALL and then select the texture you'll be using for the outside of our TELEPORTER Shell. Again I am using a TRIM texture, so I have selected ANCIENT/TRIM/TILESA. RIGHT CLICK on the BUILD A CUBE button and set it to 128x128x64. When it's all ready ADD it., then RIGHT CLICK on the BUILD A CUBE button again but this time tack on a -16 to each of the values, so you'll have 128-16x128-16x64-16. Position it like the picture below and SUBTRACT it. Then RIGHT CLICK on any clear area of the TELEPORTER Shell and then SELECT/MATCHING TEXTURE. Then RIGHT CLICK on an open space again, and under SURFACE PROPERTIES/SCALE and set to 0.5. Then highlight the front and set it the same way but to 0.25. Here's what you'll have:

Now here's where things get hairy. You see I don't tell you about BRUSH INTERSECTION / DE-INTERSECTION until the next lesson. Yet we need to do this right, so please click here at this point to get the basics down. All you need to do is RIGHT CLICK on the BUILD A CUBE button and set the values to 128+16x128+16x64+16. Now make sure the RED BRUSH isn't touching anything anywhere, and that it surrounds the TELEPORTER Shell Completely. If you followed me just a paragraph or 2 ago all you have to do is highlight the RED BRUSH, then RIGHT CLICK on it, then highlight RESET/RESET ALL POSITIONING. You'll see the RED BRUSH moved perfectly all around your TELEPORTER Shell. Cool huh? Now go up to the top of the screen and under menu select BRUSH then INTERSECT. Move the RED BRUSH to the end of the hall, centered in between the walls and aligned perfectly between floor and ceiling. ADD it, then RIGHT CLICK on the BUILD A SHEET BUTTON and set as below:

Click on BUILD and then make sure the RED BRUSH is perfectly centered on all sides and precisely 8 units away from the opening. In the 3-D VIEW if you did this right you'll see the evenness of texture there on our TELEPORTER Shell's lip. Now load up LIQUIDS.UTX. DE-SELECT ALL and then select LIQUIDS4, then select ADD SPECIAL. Now in the little list by the word PREDEFINED find WATER. SELECT it and the values should automatically change - just leave them as they are. CLICK on ADD SPECIAL and you'll now have what will have to pass as a fancy TELEPORTER or rather a psuedo-portal. In the list you may have also seen ZONE PORTAL. You follow the same steps we just did - Shell and all to make a PORTAL but instead of a WATER sheet you would use a ZONE PORTAL sheet. The only important difference between a PORTAL and a TELEPORTER is the ACTOR you use that makes them work. You will use a WARPZONEINFO for a PORTAL, and for a TELEPORTER you use a TELEPORTER. Anyhow now I have to see what values I need for this.

For now go into CLASSES/NAVIGATION POINT/TELEPORTER and put one inside the TELEPORTER Shell. Place it behind the water sheet, near the floor and centered within our TELEPORTER Shell. REBUILD and SAVE, then RIGHT CLICK on the TelePrompTer ACTOR you just added. Set as below: Noticed the red arrow pointing out of the TELEPORTER Shell? The arrows position is changed like the PLAYER START position. The arrow should point where you want your players to face when exiting the TELEPORTER. Now to build the room for the pool and other TELEPORTER. Build a cube to the following dimensions:

I placed my new room as you see above. I also set the floor level to the same as all my other constructions. I textured using ANCIENT.UTX (BRIXK3 for the walls, FLOOR2A for the floor, ACEILIN1 for the roof). I had to go into SURFACE PROPERTIES then to PAN to fit the texture to the ceiling and floor. Don't forget to add a few lights, and if it's too dark to see in the 3-D VIEW you can go to MODE directly above the 3-D VIEW window and set it to TEXTURES. Set it back to DYNAMIC LIGHTING when you wish to see how your level looks with the lights you've added. Now highlight the TELEPORTER Shell, and the water sheet. Go up to BRUSH then DUPLICATE. PRESS and HOLD CTRL while DRAGGING THE MOUSE to position the TELEPORTER Shell inside our soon to be Pool Room. Place centered and perfectly aligned on the floor flat against the wall. Don't worry if you haven't the position right, the example map is downloadable at UnrealEd Exordium - the link is below. Be sure the opening is facing into the room. Repeat the process of adding a TELEPORTER inside the second TELEPORTER Shell, and set it to, TAG=Pool Room and URL=Hallway. Make sure the arrow points into the room, away from the TELEPORTER Shell, then REBUILD and SAVE. Try it out!

Ok, we still have the original shell hanging in midair - feel free to highlight it and DELETE it. I forgot to EXPORT THE BRUSH, but this is easy enough to build anyhow. Yes, you are facing the wrong way still. RIGHT CLICK on TELEPORTER, the go to PROPERTIES/TELEPORTER/bCHANGESYAW and set to TRUE. Now it'll work, but it's needs flare, so I am going to try something. If it works I'll tell you how. No, it didn't work. I went into SURFACE PROPERTIES and set the inside walls of our TELEPORTER Shell to MIRRORED but it REALLY chewed up memory. Didn't look as great as I wanted anyway. But hey, it could be worse! Anyhow now you can go back and forth between the rooms with no hassles at all, and these will be what I use throughout the level unless I get creative and design something fancier. Now to make that pool...

Build a cube 128x256x256 and align with the center of the floor of the new room. Like so:

I am using a PANEL texture for the walls (CARVING2) and a BASE texture for the bottom of the pool (UNCARVD1). Please feel free to design yours the way you want. Now open up BUILD A SHEET properties, and create a sheet FLOOR/CEILING 256x256. Place just under the top lip of the pool, about 1 grid into the pool and away rom the floor of the large new room. It must be centered perfectly and once it is find a texture you want for it in the GENFLUID or LIQUIDS texture packs. Set as below: Add it, and then head over to CLASSES BROWSER, INFO, ZONE INFO, and WATERZONEINFO. Select it, and add below the water sheet in the middle of the pool. At this point you may want to go to DISPLAY and set the AMBIENT BRIGHTNESS to 255, and do the same again in ZONE LIGHT. Once that's done REBUILD and SAVE. Ok, we're about done. Just found out how to add movement to the water, and I figure we might as well. One way is to go into SURFACE PROPERTIES and under EFFECTS check either BIG WAVY or SMALL WAVY. The other is to use an animated texture form LIQUIDS.UTX - I am doing the latter.

Now I will give you the answer to that earlier question. It's A (but you knew that already didn't you?). Take a break, you're doing well, and I for one think it's cool we got to learn about TELEPORTERS. I was wondering if it would even work. Look what you can do when you put your mind to it. In the next lesson we'll learn how to make doors and lifts, and we'll begin basic training in BRUSH INTERSECTION/DE-INTERSECTION.

Final note on ZONES:

Before we part I thought I could explain some more on zones. Zones have to be self contained, and they can't touch anything. If zones are not properly placed they cause BSP LEAKS, slowdowns, bad effects, etc. So be careful with zones - notice I keep the grid on at all times as well as the VERTICES SNAP (more later on this). These procedures allow us to easily snap our pieces of the level together. How do we stop leaks? I don't have a clue, but that's something I will learn and teach you as we continue. Until next time...


Basic map submission

Lesson 5

By: Deathbliss

Deathbliss

Basic Movers and Bush Intersection/De Intersection:

Isn't that big opening kind of raw in our first room leading to our hallway? Wouldn't it be nice to have a door there? What about all the space in our Pool Room? Wouldn't it be cool to see something more in there? Well guess what, I've finally figured out where to go next and we'll soon answer those questions. But first I learned a few new things! To start open up the last save of the map you have been working on with me (lesson 4). Now anywhere in your SIDE, FRONT, or TOP views RIGHT CLICK in an open space. Go down the list to GRID, and guess what? Well you have a list of numbers starting at 1 and going to 256 ending in DISABLED and CUSTOM. So I selected 2, went into my pool room, and raised the water sheet to just one tiny square from the top. I didn't know this originally, and a lot of tutorials don't explain this, but if you followed me what you just did is called RE-SIZING THE GRID. I have added a little more at the beginning of these tutorials, but what you just learned is the basics. This option allows you to fine tune your level, and move pieces of geometry to more exacting positions. I went through Sniper Heaven without ever knowing this, and it leaks everywhere. With this option you NEVER need to turn the grid off. REMEMBER - RE-SIZE THE GRID if things aren't fitting right, or if you need more exacting positioning. That isn't all I learned recently either. You may have already discovered this, but the texture pack LIQUIDS.UTX has animated textures!!! Bye bye lousy wavy effect, I selected the first water texture in LIQUIDS.UTX and enjoyed a pleasant (if somewhat unrealistic) bubbly pool. MUCH better! Now on to the lesson...

Well for MOVERS I need to also briefly cover BRUSH INTERSECTION and DE-INTERSECTION: Ok, I have a hard time understanding this still, but basically when you INTERSECT A BRUSH you first must RESET THE RED BRUSH, and then make sure the RED BRUSH completely surrounds whatever you intersect but does not touch any other surface or the brush itself. Then when you INTERSECT THE BRUSH the RED BRUSH becomes the custom shape, item. piece of geometry - whatever you intersected. You can then EXPORT THE BRUSH by going up to BRUSH, then EXPORT, then naming this item and saving it in the directory of your choice. Me I placed a Custom_Brushes folder in my G:/UnrealGold/ directory. Before starting this tutorial I experimented with making archways without having to use the 2-D EDITOR (WAY advanced). This process could be used on our portals, and it's cool because it eliminates the extra subtracted brush that you can't see but depletes system resources.

To DE-INTERSECT apparently it eliminates overhanging parts of geometry and fills in the gaps. Please look at UnrealEd Exordium's Main Page and find the link to Wolf 's tutorials, he explains much better than I can at this point. I will cover this later when I learn it myself.

Anyhow let's try this. Drag your portal (just the inside and outside brushes, leaving the sheets and the WARPZONEINFO) to either a big open space in your level (such as the Pool Room) or if you have decided to use a "building area" drag it there. REBUILD, and once you have select the RED BRUSH and RIGHT CLICK on it. Under RESET select RESET SCALING and this should work right. If not try RESET ALL POSITIONING. If the RED BRUSH disappears just click on the BUILD A CUBE button in the TOOLBAR. These processes are refereed to as RESETTING THE RED BRUSH. I'm not clear as to why but trust me, it must be done before BRUSH INTERSECTION. Make a cube 150, 150, 100 and position it so it envelopes the entire Portal Shell. Check to make sure the RED BRUSH isn't touching anything, and press on the BRUSH INTERSECTION button. The RED BRUSH completely and snugly fits all around the Portal Shell. Go up to BRUSH, select EXPORT, and call it something snazzy, like PORTAL1. In the place you saved it you should now have a PORTAL1.T3D file. You merely IMPORT this when you desire to use it.

Now position the RED BRUSH back to the Portal's resting place and ADD it. I always go up to BRUSH and ADD. You can also use the following buttons on your TOOLBAR: Do this for both Portals, and delete the old shells. REBUILD and SAVE. Now soon I'll stop telling you when to REBUILD and SAVE because sooner or later you'll realize that you only really have to do these things after major changes in the level - such as ADDING or SUBTRACTING a brush. I'm re-positioning my Portal Sheets with the grid re-sized to 2 so I can place the Portal Sheet just under the front and back ledges. Once everything is in place - REBUILD and SAVE then try it out. Well see how it works!

Did you ever download the UnrealED Exordium Lesson Map? It's right there on the main page, just click the link to grab it. If you already have you may have noticed I turned the Pool Room Portal and fit it to a corner for a little pizzazz. Well guess what? Once you have followed the tutorial this far when you enter the Portal and turn sideways just inside and face the side of the Portal and try to walk through there you'll see what a leak looks like. My fancy pants portal positioning created a worse one, so I gave up on my decorating skills and placed it in the middle of the room flat against the wall. The leak is still there but not so bad now. Anyhow even the big boys at Epic that made the levels for Unreal have leaks in all of their levels or so I've read, but they're so small as to be unnoticeable. If you're having problems you can e-mail me - I'll get back to you ASAP.

Now for the door, I decided a two half door would be cool. I have only done lifts before but not doors so this will be interesting. Make a cube the following dimensions and texture to taste - I am using ANCIENT/DOOR/OTH_DR:

After you're sure it's done surround this first door half with the RED BRUSH (150, 150, 32 will cover it) and INTERSECT it. Move the RED BRUSH into position in the first room, just on the wall into which the hallway comes, and even with the floor, like so:

Find in the TOOLBAR the white box with swirly lines around it. CLICK on this button, this is the ADD MOVER button and when you have done the process on one side do the other. You'll get what you see above. Looks like I planned it, huh? Well I didn't I swear! Really, we just lucked out. Why do I only see the outline of a purple box you ask? Well here is a gripe I have about UnrealED - not only can you not see the MOVERS until you play the level, the textures can't be changed after you've made the MOVER. This is why you should have made sure that your kept any previous save before adding the mover, and that once you were completely finished texturing THEN you INTERSECTED it. Well in any case let's get these to move shall we? Go ahead an RIGHT CLICK on one of the purple boxes (your MOVER brush). We will be concerned with MOVER KEYFRAME for now. You are always one step ahead when you give your MOVER a KEYFRAME - you select where it's going before you put it there. Hence your MOVERS are at position 0 right now, which is just outside the hallway opening - dead center. Highlight and select KEYFRAME 1 and move each door separately just inside the first room, flat against the wall, with the hallway opening fully exposed:

Highlight and select KEYFRAME 0 to see if they return as seen above. Now highlight both doors and under MOVER PROPERTIES/EVENTS/TAG name the TAG something unique like DOUBLEDOOR1. Then go into OBJECT and under INITIAL STATE select TRIGGEROPENTIMED. Go into the CLASSES BROWSER/TRIGGERS and select TRIGGER (do not expand). Place this trigger right in between the two doors as seen above. Under EVENTS sent the EVENT to the same name as the two doors. Finally REBUILD, SAVE and try it out. If we did this right both doors will open as you approach, and close as you leave their immediate vicinity. There will be more on TRIGGERS later. Well I'm taking a break, I'll have to finish this a little later. Please forgive any disjointedness.

Okay I'm back. I duplicated the TRIGGER and added one on either side of the door, 7 grid units on each side. You may as well adjust this to the way you want, the way I set it allows you to run right at the door and the door opens in time for you to pass through without hitting it. I moved the FLASHLIGHT up off the floor, and tested it out. I for one am, happy with what we have, and I am ready to move on. I thought about it for a while before beginning this lesson, and I decided we needed a walkway in the Pool Room. There are two ways to do this:

1. I make a "builder room" and use two or three squares and BRUSH INTERSECTION to design my walkway.
2. I just add 3 long ramps that'll make up the walkway.

Each has it's advantages, if you go by step 1 then we'll get a smooth, neat looking walkway. If we go by step 2 we can align the textures we use to match the direction of the walkway. I am going to use step 2 for now, and maybe explain the other later. You may do as you wish, but I advise following along with me if you have any doubts. Build a cube 32x512x100, DE-SELECT ALL, and find a texture you like. I am using ANCIENT/BASE/WALLA. If you look in your SIDE VIEW (right next to the TOP VIEW) you'll see a smaller box (the First Room) then behind it a lager box (the Pool Room). Align the RED BRUSH with the roof of the First Room in the Side View because that is about halfway up the wall of the Pool Room. Place the RED BRUSH flat against the wall above the Portal, making sure it's centered perfectly. ADD it to the Pool Room. You should now have the first part of the walkway right above the Portal in they 3D-VIEW. Now we're going to ROTATE the RED BRUSH. Find this button on the TOOLBAR:

Rotate the RED BRUSH by highlighting the RED BRUSH, then clicking on the ROTATE BRUSH button. PRESS and HOLD CTRL while PRESSING and HOLDING either the RIGHT or LEFT mouse buttons then DRAG the item into position. For this in the TOP VIEW you PRESS and HOLD CTRL AND THE RIGHT MOUSE BUTTON. DRAG until it is a flat 90 degrees so you can place it against the next wall in the pool room. ADD it once you're ready. Move the RED BRUSH down to the opposite wall and ADD it there. It would be a good idea to REBUILD now, and you should see something like the picture above. I'm not giving a lot of detail here, hoping you'll be able to figure it out. But earlier on this page you'll find an e-mail link should you need assistance.

Okay, now RIGHT CLICK on the RED BRUSH and under RESET select RESET ROTATION and the RED BRUSH will be the same in all directions as the first part of the walkway above the Pool Room Portal. Or you can ROTATE the RED BRUSH another 90 degrees for the same effect. In any case it should flat against the furthest wall from the Portal. Build a cube 32x312x100 and to test it should fit right into the open space as you see above. Move it down so there's lots of space around it, texture to taste, ADD it, and surround it with the RED BRUSH (42, 322, 110 should do). Make sure the RED BRUSH isn't touching anything then RESET SCALING. Now once your sure that this part of the walkway looks the way you want (this will be the lift up to the walkway) INTERSECT it. Move it into place as seen above, then click on ADD MOVEABLE BRUSH. Now you have that purple outline again. Remember a MOVER is always one step ahead and this lift is in what will be KEYFRAME 1 right now. So RIGHT CLICK on it, and under KEYFRAME select KEYFRAME 0. Move the lift to the floor. Now do the same process again, except select KEYFRAME 1 this time and move it completely level with the rest of the walkway. Be sure it's centered, UNDO if you need to. REBUILD, SAVE as the next number up, and try it out.

Well I messed up a little. You have to jump on the ramp to get on, but it's not a big problem so I'm cool with it. We need some pillars under the walkway or something, I'm thinking that'll come in the next tutorial. Notice yet how silent our lifts are? Well in the next tutorial we'll also cover sounds. Notice how the lights emanate from nowhere? You guessed it - next tutorial we'll cover Lights, Sounds, and basic decorating. Probably also add either a door or a portal accessible from our new walkway. Is it just me or is the level (if you're following me) giving off a spooky feeling? Not sure but I thought something was going to get me - it was just going to jump right out of that portal. I wonder when we'll add a creature or too...

Good job everyone, take a break and enjoy Christmas (or you're equivalent). I won't be getting Lesson 6 up for a week or 2, unless I get a LOT of sleep. See ya soon!

Final notes on MOVERS:

When you place a MOVER into your level you have up to 8 KEYFRAMES in which to determine it's movement (0-7). After setting a MOVER'S KEYFRAME be sure to set it back to 0 (the BASE) before your final REBUILD, SAVE and PLAY LEVEL. Make sure when setting a MOVER'S KEYFRAMES that 0 (the BASE) is ALWAYS where you want the MOVER to be once you play the level. For example, if we set our doors and our lift all to KEYFRAME 1 (by highlighting a mover, RIGHT CLICKING on it, then SELECT ALL MOVERS) REBUILD, and then played it the doors would be open when you approached them, and the lift would be way up in the air where we couldn't get to it. Remember to always set KEYFRAME 0 to where you want your MOVER to be once you play the level. Also remember your mover is always one step ahead of it's next KEYFRAME, I.E. it'll be in KEYFRAME 0 before you set it to KEYFRAME 1 - you have to set it to KEYFRAME 1 before you go to KEYFRAME 1, and while you're still at KEYFRAME 0.


Basic map submission

Lesson 6

By: Deathbliss

Deathbliss

Basic lighting, sounds, and decoration:

Walkways hanging in the air aren't that cool are they? Nor is lighting coming from nowhere, and neither are lifts, doors, etc. without sound. Well it's Christmas as I start this, our tree is empty and so is my heart (at least of Christmas Spirit) at the moment, it's 3:00 AM and while I am tired I just don't want to sleep. So bear with me as I put up the next in my small series of Lessons we have been working on together. I am curious to just how I am doing, and would like to put in a survey sooner or later. First things first - we need to open up the last save of the map you have been working on with me (lesson 5). Then we need some pillars in our Pool Room. So RIGHT CLICK on the BUILD A CYLINDER button and set as below: Now I have to apologize, I usually use another paint program to get these images included, the first 4 lessons were done with Jasc Paint Shop Pro but my 30 day trial expired - so now I use Microsoft Paint. I'll improve this later if I can. Place the RED BRUSH in the center of the room with plenty of space around it. If you are using a "builder room" you can move the RED BRUSH inside and follow along from there if you'd rather. Now load up the texture pack you're going to use - I'm using ANCIENT.UTX. DE-SELECT ALL, select your texture, and ADD the RED BRUSH. I used PILLAR/COLUMN 4 for all sides, and BASE/STONETSTH for the top and bottom. Now build another cylinder following the settings below:

Align it's bottom line exactly with the top line of the pillar. REBUILD to ADD another cylinder, but this time under OUTER RADIUS set it to just 50, and align it the same way on top of the last cylinder. When you are finished it should be similar to the pic above. To get all this accurate I have placed the little red + sign of the first, second, and third cylinders all on the same dark gray grid intersection point. Now RESET the RED BRUSH and completely surround the pillar without touching anything. I just built a cube 256+16, 100+16, 100+16. Did you notice something in those numbers? Yes a cylinder needs to be only half that of a cube of the same dimensions. For example our walkways were built 100 wide. To fit a cube pillar underneath we would need a 100 WIDTH/BREADTH cube. A cylinder only needs to be 50 to be exactly the same size. REMEMBER THIS! Also the + and - in the PROPERTIES for the cylinders we are making are used to make the building processes easier. If you for instance wanted a cylinder 256, 50, 50 then wanted the cap to be about 8 units bigger you just add 8 to the number for OUTER RADIUS. Hence 256, 50+8, 50. By the way, the INNER RADIUS always needs to be smaller than the OUTER RADIUS. Is your RED BRUSH surrounding the pillar and not touching anything? Good then INTERSECT it. Now EXPORT the BRUSH to the folder you made last tutorial with the T3D files inside, and name it something like POOLPILLAR. ADD the RED BRUSH which is now shaped as your pillar to each corner of the Pool Room, centered in each corner and with the underside of the upper walkway and the Pool Room floor. DELETE the original pillar (the one you INTERSECTED), RESET the RED BRUSH, and finally REBUILD and SAVE. Here is what mine looks like (don't worry about the missing water and portal sheet, I took the picture outside the Pool Room so you get the whole effect):

Feel free to play the level and look around. Ok, finally after 2 weeks or so I'm back, and I've decided to finish up with the sounds and lighting. It's January 13th as I finish this, and we now have TELEPORTERS instead of portals in our level. In the next tutorial we'll cover the FLOOR LOFTER and advanced water. Hope you'll be ready! Anyhow, lights - well let me play around a second. Ok, it seems you can't texture something and turn it into a light (which is what I was hoping for) so we'll adopt a little of Wolf's method and add my own flare, Build a cylinder set as you see below, and go through the usual process of finding a texture you like. I am using STONTSTC for this piece of geometry.

Next we'll build a cube and set it like the pic above. I have positioned the cube at the very center of the world (marked by a dark gray circle if you look closely in the grid views) with the cylinder just underneath. I'll be using the same textures as the pillar we just created, and under SURFACE PROPERTIES/EFFECTS I will have HIGH SHADOW DETAIL checked. BUILD the cube, and then make another to the following specs:

You notice how it's perfectly centered and sticking out a little. The idea here is to create a cage that the flame will go into. SUBTRACT it here, then rotate and do it on the other 2 sides as well. Once this is done be sure to place the cage on top of the cylinder - centered with the bottom of the cage and the top of the pillar touching and overlapping each other. When you are finished create a cube big enough so that the entire RED BRUSH surrounds our soon-to-be lighting fixture, INTERSECT it, go up to BRUSH/EXPORT and call it something creative like LIGHTPOST, RE-BUILD and save. This is what mine looks like when done - notice I have placed mine around the level where I wanted them - you should do the same. Wherever you want light, place them there. Yes, I know there is nothing in there yet - that comes next.

Normally you'd do the geometry for your light and add the light source and then sprinkle them along your level. Since this level is small and I am having trouble thinking I'm doing it this way. However, feel free to do this the way you want if you are confident you can. I'm just a guidebook - you can skip a few things if you already know them. Ok, the light fixtures are as ugly as hell. Oh well, they'll suit the purpose for now. Now go into CLASSES and click on the little - next to LIGHT. Select TORCHFLAME and ADD it inside on of the light fixture cages. Whoops! Little big huh? RIGHT CLICK on the TORCHFLAME and under DISPLAY set the DRAWSCALE to 0.120000. Now your flame will fit perfectly. Next you may want to fool around with the brightness, and type of lighting until you get an effect you like. Here I am taking you off the leash, so to speak. My brightness is at 64 along with the VOLUME BRIGHTNESS, RADIUS, VOLUME RADIUS, etc. I am going to increase the ability to see it further away as well if I can. The map as always will be downloadable from the link UnrealED Exordium listed below. Well now we have a few sounds to add to our MOVERS and lighting fixtures don't we? Right click on one of the TORCHFLAMES and then SELECT ALL TORCH FLAME ACTORS. Go to TORCH FLAME PROPERTIES and then find SOUND in the menu. Open up the SOUNDFX BROWSER and LOAD AMBANCIENT from the list. Under looping find the various flame sounds. I am using AFIRE and suggest you do the same. Once selected go back to the SOUNDS menu in the TORCHFLAME PROPERTIES and find AMBIENT SOUND. Click on USE and now AMBIENT SOUND should have Sound'AmbAncient.Looping.afire5' in the box next to it. Click on the little joystick icon in the 3D-VIEW and get near on of the flames to hear it. Seemed a little high and loud to me so I went into the SOUND menu and set the PITCH to 48, the RADIUS to 16, but I kept the VOLUME at 128. Add these flames all over your level in the little holders we made and take a look around. I also deleted all my lights - I am using just the torch flames for now. It fits what I want the level to feel like except the floor needs to be lit better. So how do we add sound to the mover? Well check out this pic:

You just open up DOORSANC in the SOUNDFX browser and find some sounds that you want for the various positions of the doors, and afterwards you need to do the same to the lift in the Pool Room. I'm going to cut this short and taking a break - here I will leave you to your own creative devices. Also as I state in each tutorial, you can e-mail me if you need any help, or download the example map to see for yourself. By the way, I also added some music to the level, the name of the level and my name (the author's name). I'll show you how later - see you at lesson 7 soon.


Basic map submission

Lesson 7

By: Deathbliss

Deathbliss

Going outside... The floor lofter, advanced water, and adding ambient sounds:

Been wanting to get outside? Well I'll tell you all I know and a few tricks I've picked up along the way, but remember this is my first time too on some of this stuff. To start open up the last save of the map you have been working on with me (lesson 6) then build a cube 2000x2000x2000 and texture with something from GENEARTH. SUBTRACT the RED BRUSH and you should have a big grassy expanse. Be sure to click on TEXTURE view in the 3D-VIEW. We'll be adding lights later. Next go up to WINDOW and find FLOOR LOFTER, then open it up - you'll see this: The floor lofter I've re-sized mine so that it fits just under the TOP and SIDE VIEWS. I also suggest finding ZOOM in the menu at the top and then ZOOM OUT 2X. At this point you'll see the same thing above, but smaller. You'll also notice the red line you see at the bottom also makes up the sides. You create terrain by clicking on any of the four little squares on the blue line or the circle. Just RIGHT CLICK and drag but DO NOT GO UNDER THE RED LINE!!! It has been reported this will cause the UnrealED to crash. Also ignore the CELL SIZE and TERRA GRID options as changing these will have no effect. There are a total of 5 LEVELS and you switch between them using the arrows. The RENDER SCALE is defaulted at 256x256 and each increase is by a factor of 256x256 - hence a RENDER SCALE of 2 is 512x512, 3 would be 768x768, 4 is 1048x1048, and so on. For our room we'll need one with a RENDER SCALE of 8, so go ahead and place a 8 in the RENDER SCALE box. Now the effect we want (I have a plan and a suprise here ...) is a hilly and rough piece of terrain. Now lower the two squares on the either end of the blue line to the point that they are still above the red line (the bottom of the box) but also they are still lower than the rest of the VERTICES. Yes, these areas you are manipulating are refereed to as VERTICES. Go through all the views putting those VERTICES any way you like, and when you're done click on the box entitled RENDER there on the FLOOR LOFTER'S menu. The RED BRUSH will become a piece of terrain - here's how mine turned out at first: Top view and 3D-View of the new ground terrain Head up to BRUSH then ADD and your RED BRUSH will now place the terrain you designed in the level. Go through and center it on all sides and align it with the floor. RIGHT CLICK on the grassy texture you used for your terrain and SELECT/SELECT MATCHING TEXTURES. Go into SURFACE PROPERTIES and under ALIGN, ALIGN FLOOR/CEILING and the stretching goes away. Finally you may wish to select the walls and ceiling and texture with SHANEDAY/DAYSKY8 and under SURFACE PROPERTIES check mark FAKE BACKDROP and UNLIT. Yes, yours hangs out on all sides a bit and there's a weird box in mine. With a close up view on a grid re-sized to 2 it's precisely 3 darker gray squares on all sides if you center it perfectly. So do you desire to look around? Remember the lift in the Pool Room? On the opposite wall there's a nice blank space waiting to be filled. Go ahead and DUPLICATE your TELEPORTERS from the other parts of your level and place one in our outdoor area, and the other in that blank space - right above the lower TELEPORTER in the Pool Room. Make sure the red arrows point INTO the TELEORTER where the character will enter, and OUTSIDE where the character exits if you can. Hence the new TELEPORTER in the Pool Room will point inside itself. The one in our outside area will point - you got it - outside. When designing TELEPORTERS and apparently also PORTALS you must have the RED ARROW pointing the way the character(s) will face when using them if you want the best results. Make sure you reassign these new TELEPORTERS a new name and URL. In mine the upper TELEORTER in the Pool Room is called poolroom2 and it's URL is Out. The one in the outside area is called Out and is pointing to poolroom2. Make sure you have the TELEPORTERS placed above the ground so you can get in and out - use a flatter area if you have one. REBUILD, SAVE and take a look around. Kinda dumb without cliffs huh? Well open up the FLOOR LOFTER again and this time make terrain the same size as before, but this time design the left side buttons on all 5 LEVELS of the FLOOR LOFTER to be a little lower than the right side.

Imagine the left side as what will be the base of the terrain. See we want cliffs - so we can add a suprise, and it seems to me that by keeping the left side higher than the right we can create a realistic set of cliffs. I have NEVER done this before - let's see what happens. I am going to lower both sides some more so we actually have some space - do as you wish but try to keep the left side higher. When you're done RENDER it then ROTATE it in whichever view allows rotation. You want to place the terrain on it's left side. ADD your terrain to each wall. If you are feeling extremely creative you may design a separate piece of terrain for each wall - I'm being lazy. DUPLICATE the lights from your SKYBOX and place then near the roof of our outdoor area - remember you are trying to emulate the sun. I am using only 5 lights and I am texturing the cliffs with MSROCK3. Here is the end result of mine - your results will vary - there is no wrong answer if it looks and "feels" like cliff walls. Of course I moved my TELEPORTER to another location and now it has the effect of having been there forever as it appears to be sinking into the ground. Notice how there is no life other than you in our levels so far? This will change I assure you! Ok, now for the suprise ... We're building a waterfall and a pool for it to go into!!! Yippee!!! Ok, so it's not that great but I bet you've been dying to learn how. First off you need to think about where you want it, for me it'll be opposite my portal as there is a large dip there perfect for this. Usually you place a waterfall as if it's coming out of the rocks somewhere. Wolf advises you make a trench for the waterfall to flow along. Mine will be coming from on top of the rocks. Here are a few choices:

1. Design a trench for the water to flow along with the waterfall sheet sealing off the top.
2. Make an invisible cube that will will be sealed by the waterfall sheet.
3. Make sheets that go far into the cliff walls so there are no leaks. These must be WATER sheets with INVISIBLE check marked.

I went with option #3 and here is the result: See how the sides are completely against the cliff? Now I'm not giving exact sizes here - you have to decide that yourself. Did you notice that when you first added your water sheet that the texture didn't look anything like a waterfall? Well, there is something important you must do to get your waterfall to look good. After you find a texture you like (I'm using DNITRO7) set the assorted values by right click on the surface of your waterfall and going into SURFACE PROPERTIES. Follow the pic below and experiment if you want: Checkmark V PAN and under Scale set U& V pan to 1.0 and 8 or 9.0 respectivly. The V-PAN option that is checked is so that the waterfall flows. Is it flowing from the ground up? Well the final thing you need to do here in SURFACE PROPERTIES is go to the tab that says ROTATE and find the button that says FLIP V. Now when you click on the little joystick icon you have a somewhat believable waterfall. For the waterfall you'll need a WATERZONEINFO and you'll also need one for the pool.

At this point we have some more work to do, so feel free to REBUILD, SAVE and check it out. I decided I wanted to make everything a little finer so I scaled it down to 0.125. However, I discovered I have to re-apply the stretch and FLIP V after doing so. Looks good to me - how about a pool? Did you know the sheet doesn't have to perfectly fit where it suits? It has to seal where it sits perfectly, but we can take a square sheet and get a pool that's any design we want as long as it seals against the terrain. You know how to do this by now so I'll leave it to you. Just don't go outside the outer box, and if you have edges sticking out where you don't want try lowering the sheet under the terrain. Here's how mine looks: Pool View Well I've been struggling with this for a half hour or so - I kept entering the outside area and drowning almost because the water was everywhere. Glad to say it's fixed, and if you have the same problem here's how to get rid of it. If the problem resides in your pool seeming to be higher than the terrain in spots just make another piece of terrain that'll it fit in there and seal it. If you're a perfectionist like me than you'll just re-do the entire ground terrain until you have something useable. If the problem resides in areas of your waterfall (probably the very top more than anything else) that aren't sealed against the cliff just create a sheet to seal the gap. Make it a WATER sheet an make it's aligned on all sides and that it seals on those areas. Hmm, have I ever shown you how to widen, lengthen, or stretch your geometry? Well you use the following buttons:

Top button is SCALE - Lower button is SNAPSCALE

The top one (SCALE) re-sizes the scale independent of the grid and all at once. It's very hard to set properly.

The bottom one (SNAPSCALE) snaps onto the grid - either along the width or length. Holding the LEFT mouse button while pressing and holding CTRL will re-size the objects width, and the RIGHT mouse button with CTRL re-sizes the objects length.

Using SNAPSCALE I have made all my terrain in our outdoor area slightly smaller so it fits exactly in the box that makes up the borders of our outer area. If you've been having problems you should follow my lead. First center the terrain you are re-sizing so that it's equally hanging over on all sides. With the grid at 2 it'll be 3 darker gray squares as I mentioned earlier. Just shrink it in each direction in the TOP VIEW until it's perfectly aligned with the outer box's borders.

Now for some sounds - get over to the CLASSES BROWSER and look for KEYPOINT in the menu. Click on the - and low and behold AMBIENT SOUND is right at the top. Add the ambient sounds for the waterfall both in the waterfall and under the waterfall in the water (if necessary). I am using AMB OUTSIDE from the SOUND FX BROWSER and have select FALLS2 for my waterfall sound. You just RIGHT CLICK on the little key that represents and ambient sound, open up AMBIENT SOUND PROPERTIES and click on the - next to SOUND. In that list is a box by the words AMBIENT SOUND that currently says "none". You just highlight a sound you want then you click on that word "none" in that box and click on USE. The sound you have chosen will be displayed next to AMBIENT SOUND. At this point I'll leave you to adjust the properties any way you like. I just lowered the pitch to 50 and increased the radius to 200. Once you have everything where you want REBUILD, SAVE and test out the level. Noticed yet how you can swim right up the waterfall? Well there are a few ways to fix that. Some refer to setting the gravity high, I'm referring to Nyleve's Falls again to see how the people that did Unreal did it. Ok, here's what I've picked up in the last few hours of research. Look at the pic below, and set your two zones accordingly. REBUILD, SAVE, and check it out. You'll see that now you can't swim up the water fall and you get pushed backwards if you just sit in the water. This is similar to most waterfalls of this size and I should know because I live by few. The water doesn't look right nor is the waterfall itself perfect but the feel is there. So why did we set these properties this way? Look for the answer at the end of this lesson.

Well I got this done pretty quick - I see we need to incorporate better lighting techniques (I'm sure you agree) and maybe fine tune a few things. We'll place weapons and baddies in the next tutorial, and sometime after that or also in the next lesson we will go over designing our own decorations for our skybox - mainly the mountains since I took the lazy approach. Oh and we'll add some fog to simulate mist at the base of the fall as well - so look for the basics of creating fog soon. If you've been with me from Lesson 1 I thank you for coming back, in your case maybe my approach is what you needed and I'm glad if I was of ANY help. Just trying to give you a place to find the answers you need without wasting time searching for them. Some of the stuff in here I get from various sources on the web, and all those links reside on the main page. I hope to see you with me as we work on Lesson 8 soon! Feel free to e-mail me as always if you need any assistance. Or if you're up to it you might tell me how I'm doing.

Final notes on ZONE VELOCITY:

Ok here is what I know so far. Setting the Z variable will provide either an upward or downward force. So when you want something that pushes you up (a good example is that Quake 2 level on the N64 with the giant fan in the floor of the level) you have to set the Z ZONE VELOCITY to something positive, like 100.000000. However if you wanted a sucking or pushing motion, you have to set a negative value like -100.000000. The Y variable will push you forward or backward with the positive value pushing you forward and the negative value pushing you back. The X variable I believe determines side to side push, so if you wanted to set a fan trap in the wall you'd set an X variable that emulates the sucking motion of the fan. I believe we'll experiment with this some more later. Feel free to put my words to the test on the map we're making - just keep an extra copy of the one with the correct settings.


Basic map submission

Lesson 8

By: Deathbliss

Deathbliss

Adding stuff to your level - Weapons, baddies, pickups, music and a title:

Boy we get to have some fun here! I think item placement is one of my specialties. By now we all should have found there area we excel at (or think we excel at). I'll put myself to the test here, and you get to sit back and enjoy the ride with me. By the end of this lesson you will be able to:

1. Add weapons and pickups (health, armor, ammo, and various items).
2. Add baddies and living creatures to the level.
3. Add a title and music to you level - as I'm sure after hearing what I have done on the UnealED Exordium Lesson Map you've been wanting to learn how.

So without further ado let's add some weapons, ammo and armor. To start open up the last save of the map you have been working on with me (lesson 7). I have decided I wanted some of the weaker armor in the hallway to the side of the TELEORTER. You'll actually need the FLASHLIGHT on to see it when your first play. So this would give us a reason for the FLASHLIGHT now wouldn't it? So open up the CLASSES BROWSER, find INVENTORY, click on the - next to that, and then click on the - next to PICKUP. In that list find ARMOR and select it. Place the ARMOR on one side or the other at the end of the Hallway (the area with the windows in it - our second room). I've rotated mine to fit right in the space, and placed it one darker gray grid square above the floor. Now for the other side. What should we place there? Health? No, because you don't need it yet and why would you want to run all the way back for it. A weapon or ammo perhaps? Not exactly - you see you should have the players work a little before you get the next gun, yet going after some of the baddies with just a blaster isn't cool either. So I placed a WEAPONPOWERUP on the other side of the TELEPORTER, and this time I decided that since it's taller than the ARMOR it should be placed even with floor. Here's the end result: 3D-VIEW of item placement in the hall - armor on side and a weapon power up on the other. Now for the Pool Room. It seems to me as maybe something should be placed in the pool, and that we should have one baddie in here at least. I'm going to add 2 and see what the effect is. Open up the CLASSES BROWSER and look down the list for PAWN. Click on the - next to PAWN and look for SCRIPTED PAWN in that list. Now find some baddies to add. I've played single player a bit but I'm still not completely sure of what baddie is what. So I am placing a BRUTE on either side of the upper TELEPORTER in the Pool Room. No, check that, the BRUTE looks a little big for the ledge and our upgraded DISPERSION PISTOL. So I clicked on the - next to BRUTE and chose LESSER BRUTE from the list. Here's how I placed them: Placement of the Lesser Brutes in the 3D-VIEW Now we'll definitely need some health, so I am placing a HEALTH on either side of my lower Pool Room TELEPORTER. Get to HEALTH by opening up the CLASSES BROWSER, clicking on the - next to INVENTORY, then the - next to PICKUP. In that list you'll see HEALTH and this is what we want. If you click on the - next to HEALTH you see the various other kinds there are. Now if you survive these guys (I hope they're as tough as they look) you should get a reward, so I am placing a FLAK CANNON and FLAKSHELL AMMO in the pool and placing as below. Get to them by following the steps we took to place the WEAPONPOWERUP, and for the ammo look under INVENTORY/PICKUP/AMMO. I decided everything should be a darker gray square above the pool floor, and I've placed like below: Flak Cannon and Flak Shell item placement in the TOP VIEW. At this point REBUILD, SAVE, and try it out. I noticed a lot of slowdown so I again deleted the fancy water texture that moved and switched to a non-moving one that looked about the same. If you aren't having slowdown don't worry about this. The two LOWER BRUTES are kinda wimpy with the weaponry at hand, they fight each other and the enter the TELEPORTER. So I may replace them with BRUTES later, and I have moved them to either side of the room on the upper walkway. Now I can focus on our Outdoor Area. I wanted a school of fish in the water so open up CLASSES/PAWN/MASTER PAWN and find BITTERFISHSCHOOL there in the list. Select it and add it somewhere in the middle of the pool in the Outdoor Area. You'll get something that looks like this: 3D-VIEW of Bitterfish Pawn Actor Now there are a few unknowns at this point - I.E. do the bitterfish hurt you? Do I need to define a path for them to follow? Will the water force affect them and should it? I'm just slopping this in and we'll see what it does together. How about some birds? I always wondered if you could add a bird flock in your SKYBOX so you could see them out of the windows. I'm trying this now. Ok, I take it back - the BRUTES can be tough when they get you cornered. I may increase their intelligence. The BITTERFISH SCHOOL finished me off, so I am making them INDIFFERENT. The same applies to the birds, although I'm trying FRIENDLY for now. To get to these settings merely RIGHT CLICK on the PAWN, go to it's PROPERTIES, and under AI you'll find the various settings for intelligence and their attitude toward you. Play around with these at will. Right under AI there should may be a more specific option - in the case of the BITTERFISH SCHOOL you can determine the aggressiveness, color, radius, and size of the school. I increased the radius to 200, made them non-aggresive, and decreased the size down to 10. On the birds I increased the FOV to 128, and under DISPLAY I cut the DRAW SCALE in half. If you are following along take a break, REBUILD, SAVE and try it out. Keep adjusting things until they are the way you want. I have concluded that the birds aren't quite realistic enough in the SKYBOX so I am removing them to the "ceiling" of the outdoor area. I will still try FRIENDLY to see what they do. The BITTERFISH SCHOOL I am going to decrease to 4 then I will duplicate and add 3 schools at different locals. Here's a pic from in the level: At this point we may want to sprinkle some vegetation around the level - so open up the CLASSESBROWSER and find DECORATION. Open it up and a REALLY long list opens up. Find SEAWEED and add it to the floor of the pool in our Outdoor Area. In that list are also various plants and trees - add accordingly until it looks like you what you want. My map is as always available for download off the main page should you need a reference. Well I'm happy with everything, however we will need more ammo later on in the level. We also need to cover things like TRIGGERS and SWITCHES but I have to read up myself some more too. Need to learn how to build secret rooms, and we'll need to design a Deathmatch map so we can learn about BOTPATHING - another thing I specialize in. Once we've covered everything the best I can then we'll become a little more interactive and design concepts together. I have an idea for a room that has a fan in the floor. In any case, go up to OPTIONS, then LEVEL PROPERTIES, and click on the + next to level info. Here you can input your name, the level's name, and a few other things. Under AUTHOR I have Deathbliss and under TITLE I have UnrealED Exordium Lesson Map - input what you will. Close up that list for now and look further up the list until you spot AUDIO. Click on the + next to it to reveal a few options. Under SONG I have SACRED. Open up the MUSIC BROWSER and LOAD up whatever you want (.UMX are the music files in Unreal). You can preview the track by clicking on play. Once you find one you like leave it highlighted in the list and go to AUDIO/SONG and click on the box next to SONG. Now click on USE and when you enter the level you will now hear the music you have chosen.

Well aren't things getting pretty cool? Yet we really haven't even scratched the surface yet. There are SO many things that can be done in UnrealED. As usual e-mail me if you have any questions, comments, etc. and I hope to see you in Lesson 9 soon. Good work everyone!


Basic map submission

Lesson 9

By: Deathbliss

Deathbliss

The complete Deathmatch Map process: Creation, Preparation, and Submission:

In this lesson you will learn EVERYTHING you need to know about a Deathmatch Map while making one. The steps are roughly as follows:

CREATION:
- Decide upon a theme for your map
- Begin making the map
- Add a special feature to go along with and/or bring out your theme

PREPARATION:
- Basic BOT PATHING
- Taking a LEVEL SCREENSHOT
- Layout of weapons, powerups, items, etc.
- Making your map a Deathmatch Map
- Finishing up the map and testing it for performance

SUBMISSION:
- Every step you need to take to get your map reviewed

By the end of this lesson you will be able to easily complete al the steps listed above. You may even get to see what kind of review I get when my map is submitted. However, while this is a cool idea there are a few problems. I am the one submitting a map here as I have been wanting to take what I have learned from Sniper Heaven and create a map specifically for review so I can see what areas I need to improve in. The problem here is yours will be just like mine if you follow along with me and it'd pointless to submit a slew of clone maps by different authors. Yet you will all need to create your own Deathmatch Map eventually if that is the direction you desire to go and a review would be extremely helpful to you. To solve this I suggest you follow along this lesson, and then hopefully by the end of the lesson you'll have an idea for a map of your own. Then it's just a matter of contacting me for help if you want to iron out the rough spots. So this is the direction this lesson will take - you will learn how to make a Deathmatch Map and then your "homework" will be to create one of your own. I'll provide all the tips, tricks, and assistance as best I can. The second problem is that there are a few areas I am lacking knowledge in. For instance - it seems every time I increase the DRAWSCALE on a decoration - players can walk right through it. One of the reasons I didn't put any boulders in the Outdoor Area is that when I tried it the boulders allowed you to swim through them - very disappointing. This seems to apply to all DECORATIONS from the CLASSES BROWSER even at their default size. Despite these two hurdles we should be ok, and I have some cool ides to share with you. So let's get started, shall we? I've had an idea since my Quake map creation days for a simple theme of a level. This theme while I'm sure fairly common is interesting nonetheless to me. I will build a simple cylinder to the following dimensions: Deathmatch Map basic room cylinder properties Now one of the many flaws I have is this attitude of "bigger is better" and to be honest mostly it's untrue. This however may be too small but it'll make a quick tutorial and will help keep things simple. One thing I have learned is that when you make bigger levels they take longer to complete and you may burn out before you ever finish them. So we'll see what the other end of the scale is like here. Now I have a choice - stairs or a ramp going up. I'm going with a ramp. The idea here is a "king of the hill" style map with a few twists. You start somewhere on the walkway in this cylinder and the best weapon is on top. I'm calling it "Canned". Well I have textured with ANCIENT again to keep the theme of our lessons together, I have used GOUGEDK2 sized to 2 for the walls, AZ-FLOOR sized to 2 and ALIGNED to FLOOR/CEILING for the floor, and ACEILIN1 sized to 2 and ALIGNED to FLOOR/CEILING for the ceiling. Once you have everything looking good you may want to sprinkle some LIGHTS around and a PLAYER START, and then REBUILD/SAVE so you can look around. There are a few things you don't want to do when making any kind of map and one of them is you DO NOT want to mix styles. In other words don't use Starship textures in an ancient castle. However I will be using a lot of metal and lighting that would seem to not be apparent in a stone construction. I have a few devious reasons for this and we'll have to see how I do. Hey, what can I say? I'm a rebel at heart. Now for the ramp, build a cube to the specs below and align as seen below:

Cube properties and side view of ramp

3D-VIEW of the ramp

This ramp will be used several times in the level. Now we need a walkway around the cylinder. There's two ways to do this:

1. Build several short cubes the same width as the ramp to go against each side of the cylinder and make a walkway (otherwise known as the wrong way).
2. Make another cylinder that you can hollow out the middle of and fit it right even with the ramp (the right way).

This is yet another area mappers may stumble on - but the simplest way is as a general rule always the best way. So make a cylinder 32x512x512-16 and align it as below. ADD that cylinder to the world and then make another also as seen below - this one you will SUBTRACT from the exact middle of the first cylinder. Here's the pics: TOP and SIDE VIEWS of the walkway aligned Then make a cube 32x96x256-16. Align like below: TOP and SIDE VIEWS of the walkway hole you can pass through Now make a builder room 4000x4000x4000 and texture with something light. Drag the walkway and it's parts that you've just built into this room. Make the RED BRUSH large enough to surround it on all sides without touching anywhere, and be sure to also RESET SCALE. INTERSECT the entire thing, EXPORT it and call it something like canned_walkway then drag it back into the level. Start stacking the whole shebang (the walkway and the ramp) like so: SIDE VIEW of the all the ramps and walkways aligned No, it's not an apartment in the projects ... Be sure to DELETE all the stuff in your builder rom now that you're done with it. So we have 6 levels for players to fight on - I'd say you could have up to 12 players in here before performance drops noticeably - however I hope I'm proven wrong. Well you may as well REBUILD then SAVE AS DM_EXP1 (or your level name - Canned in my case). The DM preface tellsUnreal that the map is a Deathmatch Map. Without it your map will not be automatically playable as a Deathmatch Map. You may as well give the level a test run. You should easily be able to make your way all the way to the top now. I want to balance the level so remember our window frame tutorial in Lesson 2? Well make a cube 246x16x440-16. You'll see that it makes a nice fit with one small square space top and bottom (with the grid re-sized to 2) on the opposite side of the room from the ramps. ADD this window-frame-to-be and make another 246-32x16x440-48. SUBTRACT this new cube and you'll have a nice frame. I am using ANCIENT/BASE/MOSSROK3 and have set the size of the texture to 0.5. Make a sheet that fits right inside and texture with SHANEDAY/DAYSKYB and be sure that you have the options set to REGULAR/2 SIDED/SOLID but nothing else. Once placed in the fame be sure that FAKE BACKDROP is checked. Align and center them in the wall, like this: 3D-VIEW of the window alignment Well I decided to use a wood texture instead not only for the frames but also for the edges of the ramps and walkways. Now we need starting positions. I am placing one on each ramp for a total of 6 per side, that's 6 each on the opposite all facing each other with the windows on one side of the player and the ramps on the other when they enter the level. This will prove useful in keeping most of the fighters playing here from being disoriented when they start ;) For lighting I placed one light 1 or 2 dark gray grid unit(s) away from each window, right about at the center of the window. You all know how to make a skybox, so I'll leave you to that at this point. If you need to refer to the lesson look for the Lesson 3 link in the box below. I am experimenting with placing a piece of terrain in the skybox for a realistic set of mountains. You may do as you like, whatever I learn will be in the advanced skyboxes tutorial I'll do later. Now we need to discuss WEAPON/POWEUPS/ITEM PLACEMENT, and BOT PATHING.

First we need weapons all along the ramps. Since I am working with the version of UnrealED included with Unreal Gold don't be suprised if I mention weapons you don't have - just substitute as necessary or ignore completely. To get to the weapons (in case you've forgotten) just open up the CLASSES BROWSER then go to INVENTORY, and finally WEAPON. Everything you'll need is here, and I am placing the weapons so they are accessible right after you reach the top of the ramps. At the bottom it would make sense to have an AUTOMAG and some ammo along with some health. Seems to me the main feature of this level is to work your up to the big guns, so at the top we will have either a ROCKET LAUNCHER, EIGHT BALL, or both. On the first level I'm placing a FLAK CANNON. The next one will feature and ASMD CORE, and the one after that will feature a GESBIOSLUDGE RIFLE. The third tier will have a STINGER, and the fourth a MINIGUN. The fifth will have a RAZORJACK, and the sixth and final tier will have the EIGHTBALL. In addition I will be adding the ROCKET LAUNCHER at the top, the CAR RIFLE somewhere in the middle, and the on the floor a SNIPERRIFLE (seen as RIFLE in the list) in the shadows to spice things up. HEALTH will be placed in quantities of 1 each on each tier across from the weapons. Here is the end effect:

3D-VIEW of weapon placement

3D-VIEW of health placement

Now BOTS in Unreal aren't incredibly stupid, nor are they incredibly bright. For most of the things I place in a level for the players and/or BOTS to pickup I just click over the area in the 3D-VIEW and place it. However, you may need to check out the item(s) in all views to make sure they aren't sinking into the floor. All weapons have been placed roughly 1 darker gray grid unit above the surface it resides at. This is so the BOTS can see it more easily, and so we avoid weaponry that isn't appearing to be all there in the level. ARMOR is next and placed in a similar manner, and I think a KEVLAR SUIT (try to find it - hint it's in INVENTORY ...) at the top by the window and a normal suit by in the same area but on the floor of the level would be adequate. Okay we got the basics of the items down - feel free to sprinkle other items around like the SHIELD BELT, INVISIBILITY, CLOAK, etc. I've placed an INVISIBILITY dead center in the floor so those working their way up have some help. Be careful in your ITEM placement. For instance, DO NOT place a TOXIN SUIT in the level, as there is not toxic area for a player to enter. I'm toying with the notion of a "crow's nest" kinda thing on the ceiling, and I'll fill you in if I do it. What I want to do if I pursue this is place a key in the middle of the floor then the challenge is to make your way to the top to the snipering area. But I have to figure out how top do this. For now let's finish the BOT PATHING. Yes, you've already started it and you didn't even know it. BOTS look for and follow along a path defined by various pickups, and PATHNODES. Go into the CLASSES BROWSER and find NAVIGATION POINT in the list. Go through that list until you find PATHNODE. With the grid re-sized to 2 you should separate PATH NODES a maximum distance of 7 darker gray squares from one another. Also they should be no more than 3 darker gray grids above the floor. You must also take into account the weaponry in the level. I think two PATH NODES per ramp (one at the top, and the other at the bottom) would be sufficient, and 1 or 2 per angle of the walkway. Here's a pic of one tier completed:

PATH NODES TOP VIEW - tier 1

The yellow circles correspond to the PATH NODES. After you have done this REBUILD, SAVE, and then open up the REBUILD BOX again. Click on the far right tab which says LIGHTING. Do not change any settings, just click on the button that says PATHS DEFINE. Wait a moment, and then go into any of the views - for now the TOP VIEW will do nicely, and click on the green arrow to expose the mini menu each view has (if the menu isn't already there). Go to VIEW and click on SHOW PATHS. Now in that view there should appear some lines going from the PLAYER STARTS to the PATH NODES and/or items and weapons. This is what they mean:

1.BLUE PATHS are desirable routes. The BOTS will travel them the most often.
2.RED PATHS are not as desirable. The BOTS will rarely if ever use them.

What we need to do is determine if there is at least one BLUE PATH going up the ramp, and at least one BLUE PATH going around the walkway. In mine this may be a problem as in the ramp area I see only a REDPATH following the walkway around. I do see one BLUE PATH at least going up the ramp, and I also see a whole bunch of BLUE PATHS going from off the walkway at various points an onto the floor. This is ok for now but will be disastrous (and cool looking) later. You see even before we started pathing I tested this out with 11 BOTS and the performance was exceptional. However, I got onto the floor and it was a constant rain of gibs everywhere as BOTS fell or jumped of and died. So I am going to try moving my PATHNODES closer to the wall to see what I get. After this I moved the PLAYER STARTS back a little to the side. This cleared up the extra BLUE PATHS, and now I'm ready to test. Know how to get into observer mode? Go up to FILE and select PLAY LEVEL, once your in press ESC to get to the Main Menu, then select Spectator as your character. Find your latest DM file and select it, then start up a BOT MATCH. You can press the FIRE BUTTON to switch between BOTS - I will test with 2 BOTS for now. Be sure to either press F9 (or your screenshot button) or PRINT SCREEN on your keyboard when you are in Spectator mode. Look for a good vantage point that kinda takes in the level. You are now playing as a photographer and a scientist. The photographer part of you is looking for the best way to display his/her level,, the scientist wants to see the BOTS in action. I'm going in now ...

Okay, so they run from one group of pickups then the next, and rest a bit. This is usual but something I cannot control for now. It would be nice to make them work their way up but they serve the purpose of a gauntlet just as well. I enjoyed the feel of my match with the two BOTS, so I think we're almost ready to submit it. First off from earlier lessons you learned how to input a title, the author's name, and level music - so do that now. Next we need to classify this as a Deathmatch Map, so open up LEVEL PROPERTIES, find LEVEL INFO in the list, and then open up the CLASSES BROWSER. Go into INFO/GAME INFO/UNREAL GAME INFO and find DEATHMATCHGAME. Click on it, then go over to the LEVEL INFO list and find DEFAULT GAME TYPE. Click in the box that says "none" and click on USE. It should now say "UnrealShar.DeathMatchGame". Finally we need a LEVEL SCREESHOT so open up whatever image editor you use, and PASTE AS NEW IMAGE if you just pressed PRINTSCREEN or load the latest .BMP from the SYSTEM FOLDER in your Unreal folders area. RE-SIZE the image to 256x256. Give it a name and save it as a 256 COLOR BITMAP. Go back to UnrealED and open up the TEXTURE BROWSER. IMPORT the file and fill out the box that pops up as follows:

NAME: Screenshot
GROUP: None
PACKAGE: Mylevel

Then either leave the generate mipmaps unchecked or checked - your choice. Unchecking it seems to give a worse picture. DO NOT SAVE THE PACKAGE WITH YOUR SCREENSHOT IN IT!!! Go up to OPTIONS, then LEVEL PROPERTIES, and next find LEVEL INFO in the list. There should be a box that says Screenshot "None" in there. DE-SELECTALL then select your level picture (you'll see it in the list of texture packages as Mylevel now), and click in the box that says "none" and click on USE. Now when you open up this map, and all consecutively saved maps, you'll have a pic of your level.

Well all you have left to do is to BOT PATH each tier all the way up to the top. There is a little trick I'll tell you about so you can fool around with it. Right click on any weapon and go into it's PROPERTIES. Go into INVENTORY and find MAX DESIRABILITY in the list. By increasing this number you increase how badly BOTS want it. Something I picked up researching, feel free to test it out. Once you're all done REBUILD/SAVE, and take a deep breath. You are now going to learn how to submit your map. There are two main places to do this:

1. For specifically Unreal Tournament designed maps you should try Unreal Tournament Underground AKA UTUG. However, there are reviewers there that will review Unreal Maps if you ask nicely.

2. Since we are dealing with Unreal the next best place is Nali City.

There are 2 ways of submitting your maps - and in Nali City I believe you may have to sign up first. One is by e-mail (which they really don't like) and the other is via FTP. If you have a FTP (File Transfer Protocol) program and already know how to use it cool. Just upload your map into their directory. If not then the simplest way is in Netscape Find the Submit(FTP)files link and click on it. Then once the page loads go to FILE in your browser, and then UPLOAD FILE. Simple huh? for Internet Explorer you're on your own - sorry but I can't figure it out yet.

Well now you can create Deathmatch maps with ease and you can even BOT PATH them which few know how to do. You can take a pic of you level and when your level is clicked on in the Deathmatch Maps list it'll show the pic and give your level a professional appearance. Finally you now know how to submit these levels you create for others to review - which I recommend doing often so you can discover your rough spots. My compliments to you all, your dedication if you have been with me this far is phenomenal. We still have to answer a few questions, I.E. how would we get a BOT to use a lift, or trigger a trap, etc.? How do you make those mountains in the SKYBOX? Plus many more I'm sure. We'll answer some of those soon, I haven't decided where to go from here but most likely it'll be advanced skies, or advanced BOT PATHING. Once we've covered all the ground I can with you (and we're getting close) we'll start experimenting and trying various concepts together. At that point it'll be your turn to contribute, and to provide us all with fresh new ideas that will teach us new things. I'll start it off with my idea, and then I'll wait for you to e-mail me with yours - we'll continue from there. Now I leave you with a few notes.

Final notes on LEVEL SUBMISSION:

Here are a few things that I'm guessing reviewers look for in a level - I'll add to this later if I can:
1. Continuity - Both in the texture alignment, the flow of the design, and the level theme.
2. Performance - How well dos the map perform? How far can I push it? Is there any slowdown?
3. Flaws - For example are there any BSP LEAKS (when I'm looking around the level will I find invisible holes, and areas where a HOM ((hall of mirrors)) effect is evident)?
4. Features - Can I play against BOTS?
5. Balance - Does the fighting ever stay one-sided anywhere in the level?
6. Originality - Have I seen this before?

There's more I'm sure but basically a map reviewer is a level tester. As a map reviewer you may not be getting paid, or be in the gaming industry per say, but you have to do the same things as level tester would. You have to try to make the level crash, and test all the limits. Then you get to decide what to rating the submitted will receive. Please note that these are not official standards and each map reviewer may have different criteria - either less extensive or more extensive, so take these statements with a grain of salt. Follow them as best you can, and you should get a better score. That's what this little closing section was written for. I'll know more after they review my map.


Basic map submission

Lesson 10

By: Deathbliss

Deathbliss

Comprehensive Movers and Triggers:

- Part 1 -

I though we could do some touch ups on the level we've been building from lessons 1-8. Hope I broke up the monotony a bit by throwing a Deathmatch Map tutorial in lesson 9. There are a few areas I need to expound on:

1. All the details on TRIGGERS
2. All the things you can do with TRIGGERS
3. What kinds of TRIGGERS there are

Also not related to TRIGGERS per say I found some areas of our map that could be improved. The lights, buttons for the doors and lifts to work, a place for our Pool Room lift to set, the in's and outs of the skybox, and more. So as I finish up the lessons as we prepare to move on to prototype mode I thought I'd iron out some rough spots.

To start open up the last save of the map you have been working on with me (from lesson 8). I've decided to delete the old Pool Room MOVER and I have built a cube 32Hx256Wx96B (H=HEIGHT, W=WIDTH, B=BREADTH). For now we can ignore WALL THICKNESS (for hollow cubes mainly) and GROUP NAME. Re-size the grid to 2 for the easy manipulation of our geometry and place this RED BRUSH as seen below: Alignment in the TOP and SIDE VIEWS of the Pool Room Lift Hole If you followed along with me when we built the Pool Room and/or have the same texture I used on the floors, you'll see that when we subtract this it'll align perfectly with the texture pattern. Whatever texture you used for the floor, at this point you can DE-SELECT ALL and then find it in the TEXTURE BROWSER. Click on that texture, then SUBTRACT the RED BRUSH. Here's what mine looks like: 3D-VIEW of the Pool Room lift's resting area Now here is a good area to practice texture alignment. I had to FLIP Uon mine in some areas and PAN to get it to line up like what you see above. This area really doesn't matter but still a little extra detail never hurts (TOO much ...). Now all you need is another cube the exact same size or maybe just a hair smaller. For me I am making a cube the same HEIGHT, but the WIDTH and BREADTH are going to have a -2 tacked onto the end. These dimensions then are 32Hx256-2Wx96-2B. After you have done this move the RED BRUSH to a clear area - such as the center of the Pool Room. ADD it there once you've selected a texture you will use, and remember you will not be able to change this later so if you want to keep your original lift off to the side somewhere do so at least until you are happy with the new lift. I am using ANCIENT/TRIM/ TILEMOS5 this time for a little color. Once done make a cube large enough that the RED BRUSH completely surrounds this new cube and INTERSECT it. If it doesn't work RESET ALL and then drag the RED BRUSH back to where you want it. Take the RED BRUSH after you've INTERSECTED it to the little hole in the floor we've created and place it inside - perfectly centered and just above the floor - the bottom of the RED BRUSH just touching the base of the hole (or you can leave it 1 grid unit above the base of the hole by re-sizing the grid to 1 and position from there). Find the ADD MOVER icon on the TOOLBAR ADD MOVER button and click on it. You can now RESET ALL on the RED BRUSH and it'll be ready for when we want it next. Now set the KEYFRAMES by RIGHT CLICKING on the purple box (the MOVER that will be your lift) and finding MOVER KEYFRAME in the list. Remember from our lesson this that you set the MOVER ahead of where it will go. So you select KEYFRAME 1 and then move it to KEYFRAME 1 (which will be perfectly aligned and even with the walkway above) and once it's there your do the process again but this time you'll select KEYFRAME 0 and it should return to it's resting space. If not keep setting the KEYFRAMES until it does. Be sure to add sounds if you want. REBUILD, SAVE and check it out. Here's mine: Pool Room lift keyframes: Keyframe 0 (left) and Keyframe 1 (right) Now for a TRIGGER ... Well for TRIGGERS to work we know by now that you need to name an object's TAG and then you need the trigger's EVENT to be the same name as the objects TAG. In lesson 5 we called the door movers DOUBLEDOOR1 and then put a TRIGGER on either side or in the middle of the door mover. We then set the triggers EVENT to the same name as the TAG of our door movers. So each door mover would have DOUBLEDOOR1 as it's TAG and each TRIGGER would have DOUBLEDOOR1 as it's EVENT. This is how this type of TRIGGER basically works. However, you can use a MOVER for a trigger, and this is how you would create a switch that would activate something in Unreal. Getting the idea? You can make trap doors, traps, secrets, and we're going to learn how to right now. First off create a cube 33Hx33Wx32B. Align it like so: TOP and SIDE VIEWS of the Pool Room switch alignment Find a texture you like - I'm just using a texture sparing ANCIENT/BASE/UNCARVD1. Now drag the RED BRUSH to the middle of the Pool Room again (or any clear area you prefer) and make another cube 32Hx32Wx32B. Now if you look in the ANCIENT texture list you'll see SWITCH in there among the types of textures. Open that up and select it once you've DE-SELECTED everything. ADD this new cube (which will become our switch), INTERSECT it and then drag it into the hole in the wall. ADD MOVER there and set KEYFRAME 1 to be inside the hole completely and aligned on all sides, and KEYFRAME 0 by dragging it back out and resting it just on the opening of the hole. Here's a picture: Pool Room switch keyframes: 0 (right) keyrame 1 (left) Now RIGHT CLICK on the switch and go into MOVER PROPERTIES. Look for EVENTS and expose the list there. Leave TAG alone but under EVENT put prlift into the box (pool room lift - get it?). Next you need to RIGHT CLICK on the lift and under MOVER PROPERTIES/EVENTS/ place prlift in the box next to TAG. Now also in that list you need to find OBJECT then the word INITIAL STATE. There you select TRIGGER OPEN TIMED from the list. What does all this do in English? In a nutshell the game says, "Hey, here's a lift named prlift and it's operated by a trigger - AH HA! Here's the trigger controlling it!" However all you'll see in UnrealED is that RED LINE connecting the two objects. Basically that's what that RED LINE that appeared is telling you (in case you hadn't already guessed that ;). REBUILD, SAVE, and see if it works. Well I noticed a few things - for one I might want a sound. For another it looks dumb having the lift go right through the switch, so to solve this I'm changing the position of KEYFRAME 0. By the way, I just discovered you may have to reset not only the switch's keyframes but the lifts as well. I guess that RED LINE also determines the position of the things it's connected to. Everything else is cool, and we got the height perfect it seems. So we need to explore some more uses of the TRIGGER once we're happy with this. Let's work on triggering some lights. I've come to the conclusion that my lighting sources are lame so I have spent some time creating something that looks pretty good. the map as always is download able for the Exordium Main link at the bottom of the page. I think a trigger you have to shoot at to activate would be cool, so build a cube 33Hx33Wx32B and set above the doors in the First Room and align like so: 3D-VIEW of the switch hole above the First Room doors Next make a cube 32Hx32Wx32B and position in any available open area. This will be a lot like what we did with the mover and switch combo in the Pool Room. ADD it, RESET the RED BRUSH, build a cube large enough to go around the newly added switch-to-be and INTERSECT it, place the newly intersected REDBRUSH into the hole, and finally click on ADD MOVER. KEYFRAME 0 will be outside the hole, KEYFRAME 1 will be inside the hole. Now we have some MOVER PROPERTIES to set. Under EVENTS set the EVENT to tlights and the TAG to Trigger. Under MOVER set DAMAGE TRIGGERED to TRUE. You should fool around with the other settings to, some are self explanatory and some are not. For instance, you could make this TRIGGER work just once. Now you need to open up the CLASSES BROWSER and look for LIGHT. Open that list and you'll see 2 types of TRIGGER LIGHTS. We will be using the first one (with NO asterisk). Set these in our light sources in the First Room after deleting the old light sources (if you followed me then that's the torch flames) but keeping the holders. I have a new holder I have created that will be included with the map for you to download. All you do is go up to BRUSH then IMPORT and find the area where you placed ANCHOLDER3 then double click on it. Don't change the options in the box that comes up, click on OK and then you can position at will. If you're still using the torch holders that we made earlier you just place a TRIGGER LIGHT inside where the flame was. For the ANCHOLDER3 you place the light in the glass case area. Be sure to open up all the TRIGGER LIGHT PROPERTIES once you have them all placed and find TRIGGER LIGHT in the list. The two top settings are fine for now - BDELAY ON FALSE and BINITIALLY ON FALSE are the defaults and are what we want. Unless you want to turn the lights off when the switch is pressed in that case BINIATIALLY ON would be true. But we want to turn them one on and in this lesson I will show you how. Ok now find OBJECT and under INITIAL STATE be sure to select TRIGGERTURNS ON from the list. Now go up to EVENTS and set all the TRIGGER LIGHTS TAG to tlights. Leave the EVENT alone. REBUILD, SAVE, and try it. When you start the room should be dark but the switch will be glowing up there. Shoot it and it will turn on the lights.

Well by now you are beginning to see what you can do with a TRIGGER. I think we'll add more as we go along, and I also feel that we have a new room to create soon. There are a few more things at this point we need to do. The first is to tell you about the DISPATCHER. This is a special TRIGGER that keeps tracks of multiple special events. Say you wanted an EARTHQUAKE TRIGGER, then the lights to go out, then perhaps some explosions. You'd place these triggers where you wanted them in the level, then you'd place a DISPATCHER where you wanted these events to begin. In the ADVANCED PROPERTIES under DISPATCHER you would place the TAG names of your TRIGGERS in the order in which you wanted them to happen, so when the DISPATCHER is activated it would activate each TRIGGER in turn. I should demonstrate this here but this is getting long winded to begin with, and that's a more advanced topic. I'm not feeling that well at the moment and I want to get this up so we will close here. I'd like to expound on TRIGGERS later so the next one will continue this. Good work everyone! Hope you picked up some things that will help you make some of your ideas a reality. See you in the next lesson!


Basic map submission

Lesson 11

By: Deathbliss

Deathbliss

Comprehensive Movers and Triggers:

- Part 2 -

Ok let's keep exploring TRIGGERS. This lesson will take off from the last one. To start open up the last save of the map you have been working on with me (from lesson 10). Now we need a new room, so build a cube 512Hx512Wx512B. Place it somewhere convenient and away from all the other rooms by 6 dark gray units (with the grid resized to 2). Here's where I put mine: TOP VIEW of the secret room Find a texture you like and SUBTRACT it into the world. I am using those from ANCIENT as usual, for the floor I'm using FLOOR2J1, for the ceiling ACEILIN 1, and for the walls BRIXG2A. After you have added it, and if you are following me you need to build another cube 128Hx48Wx96B and place it even with both the floor of the Pool Room and the Secret Room. If the two floors are not aligned be sure to adjust the Secret Room's floor until it matches the Pool Room's floor. Be sure to REBUILD and SAVE if you move anything. Then SUBTRACT this new cube once it fits between them and then position it like so: TOP VIEW of the hallway alignment between the Pool Room and the Secret Room If you are exploring your own way all you need to do is to make a hallway that fits in between the two rooms. It should be at least 128H and 32W to accommodate the player's size. The goal here is to make this a secret, so once your hallway is in place create a cube 128Hx48Wx16B for a door. Place the RED BRUSH in an open space - the Secret Room is the best choice here. If you are using a different size hallway what you need for a door is something the exact same dimensions - but thinner. Texture as you like and ADD this door to the world, RESET the RED BRUSH (ALL POSITIONING or SCALE), and then make the RED BRUSH big enough to surround our door. Once that is done INTERSECT it and drag the RED BRUSH into position. ADD MOVER there and set the KEYFRAMES. I decided I wanted a 3 position door and I figured it out! Under MOVER PROPERTIES find MOVER in the list. Here are some things to note:

1. BDAMAGEDTRIGGERED means you have to shoot at the MOVER (causing damage) to activate it.
2. TRIGGERONCEONLY is just that - the MOVER only operates once.
3. BUMP EVENT determines if it operates something when touched. If you set this to TRUE you would then need to set the BUMP TYPE.
4. DAMAGE THRESHOLD determines the beating it will succumb to before operating.
5. DELAY TIME means just that. Do whatever you have to to operate it but it wont work until the timer has finished counting.
6. ENCROACH DAMAGE - how much this sucker hurts when it's in contact with you.
7. KEY NUM - use this setting to determine where the MOVER'S base point will be.
8. MOVER ENCROACH TYPE and MOVER GLIDE TYPE give you settings for the MOVERS operations.
9. NUM KEYS - VERY IMPORTANT!!! If you want the MOVER to have more than 2 settings increase this accordingly. It's set so that you have an OPEN and CLOSED position, for me to get the secret door to work right I needed to set this to 3 so that it could move back and to the side.
10. PLAYER BUMP EVENT works with #3 in this list. The EVENT here is the TAG of the object that the BUMP EVENT activates.
11. STAY OPEN TIME is just that - how long with this door stay open?

If I have excluded any settings it is because I am not sure of them myself just yet. I will however continue to tell you what I learn as I learn it. Ok, well you now how to do a switch for now. I'll leave the settings up to you and maybe we can trade maps around and test each other. Here's the assignment - make this secret door operate in a special way and don't tell the person who will test it. For example you may want the door to be shot at for it to open, or you may want a switch hidden somewhere open the door. Whatever you want, mine will be available for download as usual on the main page of UnrealED Exordium.

Now as we near the end of this lesson we should cover the DISPATCHER. Open up your CLASSES BROWSER and find TRIGGERS in the list. Locate TRIGGER and do not expand. Place a TRIGGER just after the door into the Secret Room. Now find DISPATCHER and place one just inside to hallway going to the Secret Room so when you (or the player) enters the door and before entering the Secret Room they'll set off a series of events. Open up the DISPATCHER PROPERTIES and under event place a unique name that will also be the TAG of the first TRIGGER. Open up DISPATCHER PROPERTIES/DISPATCHER and take a look. Under OUT EVENTS you start at 0 and work your way up. Now open up the INVENTORY list and under PICKUP find TRANSLATOR. Place this just beyond the DISPATCHER. Go back to TRIGGERS and place a TRANSLATOR EVENT just after the TRANSLATOR. Open up TRANSLATOR PROPERTIES\EVENTS then under TRANSLATOR EVENT find MESSAGE. Type a brief message in the box. Now open up the EVENTS menu. Under EVENT place DISPATCHER and under TAG place the same thing you'll put under DISPATCHER PROPERTIES/DISPATCHER/OUT EVENTS. There are 7 of these OUT EVENTS and if you wanted to do more you'd just make the last OUT EVENT connect to another DISPATCHER. The OUT DELAYS correspond to the OUT EVENTS so if you wanted the DISPATCHER to delay an EVENT you'd just place the amount of time under the number of the EVENT in that list. Now just inside the room place a SPECIAL EVENT TRIGGER and set its EVENT also to the DISPATCHER and for it's TAG think up a creative name. Still in the CLASSES BROWSER open up KEYPOINT and find EARTHQUAKE in that list. Place an EARTHQUAKE just after the SPECIAL EVENT. Make the EARTHQUAKE'S EVENT be the same as the TAG of the SPECIAL EVENT and it's TAG as something unique - like eq. You could then place eq in the DISPATCHER'S OUT EVENT list. Getting the idea? Oh - here's a pic: TOP VIEW of trigger placement I'll leave you to your own creative devices at this point. These last two lessons may be enhanced later. For now you are getting the idea. The basic rule of thumb is this:

1. TRIGGER A's EVENT name needs to be the same as TRIGGER B's TAG name.
2. TRIGGER B's TAG name needs to be the same as TRIGGER A's EVENT name.
3. TRIGGER A is now activated by TRIGGER B.

You can now link other types of TRIGGERS to the DISPATCHER. Some will need SPECIAL EVENTS to operate, some won't. You can add a MUSIC EVENT TRIGGER to change the music in the level, or a TRIGGERED DEATH for a trap or misleading switch that will kill the player. Explore and if you have any questions feel free to e-mail me. If something isn't working try it first without a DISPATCHER, then check out it's PROPERTIES/OBJECT list and make sure everything is correct there. MOVERS can be operated various ways, and they should be pretty self explanatory. I may go more into depth later or maybe even add another lesson to this series. For now I'm taking a break for a while. Soon we will enter Prototype Mode and I hope to see you there.


Basic map submission

Introduction to UnrealEd 2.0

By: Deathbliss

Deathbliss

A comprehensive introduction to Unrealed 2.0:

OK, I've been a little lazy... I've also been involved more in my reviewing at UTUG and my map making. On top of this I've been feeling - well - directionless on how to teach this set of lessons. I want to follow a similar formula to my original set for UED, but I also want something different, unique, and cool. So I finally decided to try this - we are going to build an orbiting space station. It would be the easiest thing to light, and since my UED lessons used an Ancient theme it's fitting that my UED 2.0 lessons cover a Futuristic theme. It's still going to be hard to design something and stick with it, and it's going to be hard for you - the readers - as well as I intend to throw you into the virtual pool of editing so you can learn how to swim. I'll try to be descriptive, and I guess we'll just have to see if it's sufficient. So as always if you have any trouble understanding these lessons or any questions - send me an e-mail. Now, it may help you to be familiar with the basics of the editor, and you can so by clicking here. I also use a variety of custom brushes and textures, so be sure that you have Unreal Tournament patched to 436 and that you have all four bonus packs installed. It will also help you to have all the textures and music from the original Unreal on your machine - as we may use these as well. However, if you do not own Unreal don't worry - I suggest getting a copy (it's like $10.00 at EB) but it is not necessary for these lessons. I use Tarquin's Custom Brush Builders more than any other custom builder out there - and you can get them here.

Once you have everything installed and ready open up UED 2.0 (it's there in your UT directory under SYSTEM/UNREALED.EXE). I suggest adding it to your start menu group or placing a shortcut on your desktop for easy access. OK at this point you should see a confusing array of 4 windows, and a toolbar on the left side as well as a toolbar on top. Above the top toolbar are some menu items, and at the bottom of all this is an empty box next to the word Command with a few little icons next to it. In the top toolbar click on the little icon that looks like a scenic picture. You should be confronted with a window that says TEXTURES and it'll be showing the default textures for the editor and UT. Right under the word FILE is an icon that says TOGGLE DOCK STATUS if you hold your pointer over it. I want you to click on that - you'll see why in a sec. You may also want to see you textures at a bigger size - so while in the TEXTURE BROWSER go to VIEW/SET SIZE and use 128. A checkmark will appear next to the selected variable - use what you like best here. Click on the pawn icon to open up the ACTOR CLASSES BROWSER and do the same to it as you did for the TEXTURE BROWSER. Now you should have a box with a few menu items in it at the top, and two tabs that when clicked will switch between the two browsers we opened up. I use this layout all the time and I recommend you try it as well. Do the same for the MUSIC and SOUNDS BROWSERS, so you'll have 4 tabs in that box now. Click on any edge to re-size the box - I usually cover the TOP and SIDE views since I rarely use them. If you click on the little minus symbol on this box it'll reduce to a little tiny thing at the bottom of your screen. Clicking on the open box symbol will open it back up. Makes for very easy access to what you want when you want it. I'll explain the various icons we click on as we go along - if you listened to me you watched my viewlett so you'll have a pretty easy time understanding everything. Let's get editing shall we?

In that left toolbar resides an icon that when the mouse pointer is held over it reveals itself to be CYLINDER. Coincidentally, it shows a picture of a cylinder on it. This like all the other basic brush builders in the editor can be clicked on to build a default of that item, or they can be RIGHT CLICKED on so you can input your own values. We are only concerned with the first 4 numbers for now they are in order HEIGHT, OUTER RADIUS, INNER RADIUS and SIDES. I will refer to them from now on as H, OR, IR, and S. We will use this formula - H=256, OR=512, IR=512, and S=8. In English for the final time that is HEIGHT=256, OUTER RADIUS=512, INNER RADIUS=512, and SIDES=8:

Once you have inputted the numbers provided click on BUILD, and then CLOSE. In the editor in all the views you should see a bright red Cylinder. Pretty boring huh? Let's flesh this puppy out now...

Click on the tab that says TEXTURES. Go to FILE/OPEN/STARSHIP.UTX. DOUBLE-CLICK on this file and a new bunch of textures will appear.

NOTE: ALL TEXTURES FROM UNREAL/UNREAL TOURNAMENT (actually ANY Unreal Engine based game - such as Wheel Of Time and Rune) END WITH AN EXTENSION OF .UTX!

These go into your Unreal Tournament directory in the TEXTURES folder. So if you ever get a custom map and it has a .UTX file there that's where you put it. There are two drop down boxes right below the icons in our big box here. The top one lets you switch between the different texture packages you have loaded. The lower one just underneath it will let you browse the various sub-catagories of the texture package you have selected. Using the lower drop down box find WALL and click on it - we'll use SH_WL3 for now. Select this texture - and a greenish box should appear around it. Go up to BRUSH, and then click on SUBTRACT. Unlike Quake Engine games Unreal Engine games are solid. I picture them as blocks of wood. The RED BRUSH is your carving tool. So you carve your level out of the void. Please remember - the RED BRUSH is not going to be seen in your level. It is invisible, and is only what you use to create your level.

NOTE: In Quake Engine editing you add to the void. In Unreal Engine editing you SUBTRACT from it - REMEMBER THIS!!!

Well now you are in a Cylindrical room that looks cool but also kind of dumb huh? Here's where we learn about TEXTURE ALIGNMENT! RIGHT CLICK on any wall, then brows to SELECT SURFACES. Click on ADJACENT WALLS and you should have all 8 walls (remember we used 8 for the SIDES variable) selected. Now RIGHT CLICK on any of the selected walls and go to SURFACE PROPERTIES - it should say 8 SELECTED right next to it in parentheses. In the box that pops up this repeats again at the top and it also tell you what texture(s) are(have been) selected:

Find the tab that says ALIGNMENT and somewhere in there is an empty drop down box next to the word SIMPLE. Sometimes it's hard to switch between the FLAGS and ALIGNMENT tabs due to a glitch in the editor - just keep trying until you find what I'm talking about. Once you got that box click on the arrow next to it and find 2.0. Select that, and in the list of buttons to the left of this click on WALL DIRECTION. Now click on the APPLY button to the right of the drop down box where the value 2.0 is now displayed and walla! You'll see the wall texture get bigger and fit a little better. Now I thought it still looked funny - but I also saw that the bright area in the middle opened up some intriguing ideas, so after doing all this find the section here under the word ROTATION - it's right above the ALIGNMENT and SIMPLE SCALING options we just used. Click on the button with 90 on it and low and behold! Suddenly the walls look pretty neat. Now use your creative instinct and find a suitable FLOOR texture for the floor, and a CEILING TEXTURE for the ceiling. I suggest either BASE, CEILING, or FLOOR textures for these areas. For my floor I'm using SH_BS7 and for my ceiling PANEL3. Be sure to RIGHT CLICK on each of these, then under SIMPLE select 1.0. Then with those surfaces still selected (you can do both the floor and the ceiling at the same time by clicking on either one, and then pressing and holding CTRL while clicking on the other) select ALIGN TO FLOOR and finally click the APPLY button next to SIMPLE.

NOTE: ALL FLAT SURFACES ABOVE AND BELOW YOU SHOULD BE ALIGNED TO THE FLOOR, AND ALL FLAT SURFACES BEHIND AND IN FRONT OF YOU SHOULD BE ALIGNED TO WALL DIRECTION.

Keep this in mind as a GENERAL RULE - it does not always apply. OK, a few more steps and we're done. Well I guess we may want to explore our room - but first we need to go to BUILD/BUILD ALL. This step is very important - if you DELETE any brush or alter the level in certain ways IT WILL NOT SHOW UNTIL YOU REBUILD!!! So remember this. After REBUILDING you should go to FILE/SAVE AS. Call your level DM-SpaceStation1 and SAVE it. Now you need to go into our window where the TEXTURE BROWSER and the other assorted browsers are and click on the ACTOR CLASSES tab. Click on the plus next to ACTOR, the plus next to NAVIGATION POINT, and then find PLAYER START:

Click on that, and then anywhere in the 3D VIEW (the view that shows all your cylinder all dressed in pretty textures) ABOVE THE FLOOR RIGHT CLICK and ADD PLAYER START HERE. Moving around here (in the 3D VIEW) is done with the mouse, PRESSING and HOLDING the LEFT MOUSE BUTTON allows you to move backwards and forwards, and also gives you the ability to turn left or right. PRESSING and HOLDING the RIGHT MOUSE BUTTON lets you look up and down in any direction. PRESSING and HOLDING both the LEFT MOUSE BUTTON and the RIGHT MOUSE BUTTON will allow you to strafe left or right, and to move straight up or down. Once you got the hang of it RIGHT CLICK anywhere inside your cylinder looking at the ceiling and ADD LIGHT HERE. REBUILD, SAVE AS DM-SpaceStation2 and then under BUILD highlight and select PLAY LEVEL. You should be able to expore your room now. No, it's not mind bogling just yet but we'll be working on that in the next few lessons:

NOTE: To remember to SAVE use this simple phrase - S.O.S. - or for you denser types SAVE OFTEN STUPID!!!

Congratulations! You created your very first level for Unreal Tournament. Some of the greatest buildings were started with the smallest of bricks, and with the foundation we lay here and whatever natural talent you have you should soon be seeing some truly great things from yourself as a Mapper for Unreal Tournament. The next few lessons will continue to go over the basics and repeat a few important things so you grasp them better, I would assume that once you are familiar with the editor you will be able to take off on your own. I hope you follow through all of the lessons I'll be putting up first though as I learned the hard way that wanting to do something but not knowing how is the worse curse you can put on yourself. I intend to leave no mysteries with the editor here, I want to make sure there is nothing stopping you other than the limitations of the editor from creating whatever you want. The rest is up to you - see you in lesson 2!


Basic map submission

Getting More Familiar with UED 2.0

By: Deathbliss

Deathbliss

Getting more familiar with UED 2.0:

Well having a light coming from nowhere is one of the ugliest things you'll ever see in a level. Surprisingly as a reviewer at UTUG I run across this a lot, and of course it affects the rating. Light should always have a source, as we generally try to follow a few fundamental rules from our own world in Unreal Tournaments'. Plus if you're good at lighting you can really show off a level - lighting affects the atmosphere and appearance of a level even more than the level's design itself. So let's get on with it and create a light source!

NOTE: Lighting should ALWAYS have an ACCURATE source!

In the left toolbar find the icon that displays a green cube and RIGHT CLICK on it. Set the variables to H=16, W=16 (Width=16), B=16 (Breadth=16):

Don't worry about WALL THICKNESS, like the Cylinder's INNER RADIUS this value is only important when making a hollow version of these basic shapes. Click on the RED BRUSH so it's highlighted (a highlighted brush always turns a brighter shade of it's original color when selected by clicking on it) and then RIGHT CLICK on it. Find RESET and then select RESET ALL.

NOTE: RESETTING THE RED BRUSH is vital after and before any altering of any kind done to the RED BRUSH. Basically just RESET THE RED BRUSH after every use.

The RED BRUSH should move to the exact center of the level. Now at the bottom right of the screen is a drop down box that probably says 16 right now. Click on that arrow and select 2. You can also do this by RIGHT CLICKING in any of the grid views (TOP, SIDE, or FRONT) highlighting grid and selecting 2 GRID UNITS. This is referred to as RE-SIZING THE GRID. I use 2 because I get a much finer manipulation of things in the editor. To the right of the aforementioned drop down box are two icons, TOGGLE ROTATION GRID and MAXIMIZE VIEWPORT. To the left of the drop down box are TOGGLE DRAG GRID, and TOGGLE VERTICE SNAP. There is also a SHOW FULL LOG WINDOW but we aren't concerned with that. Makes sure the three grid controls are green (this means they are on). Click on the MAXIMIZE VIEWPORT You'll see the 3D VIEW get larger. Click on it again so it goes back to normal. Make sure the RED BRUSH is highlighted, and keep a note of what we just learned. We need the RED BRUSH at the ceiling of the level - just above it in fact. To move it use either the FRONT or SIDE VIEWS and place the mouse pointer in there over the RED BRUSH (in the case you were moving something else you'd place the pointer over that). PRESS and HOLD CTRL and DRAG with the mouse until the bottom of the RED BRUSH is even with the top of the subtracted cylindrical room. In the TOP VIEW make sure that the RED BRUSH is right in the middle of the room - move it the same way if it's not until it is. If you click on the subtracted room (it'll turn bright yellow) you'll see one of those squares right in the center of it. The center of the RED BRUSH should be aligned to this. Now in the 3D VIEW you'll see that at each corner is a little square - these are called VERTICES. Click on any of the bottom ones so that a little red plus appears:

Now in the TOP VIEW drag the vertice to the edge of the darker gray grid unit. This is 4 units to the side and then 4 units up. The darker gray squares are actually 16 units. We started at 16x16, and we are increasing it to 32x32 (in the TOP VIEW). The perfect size for a stair height is 16 - might want to make a note of that. In UT the players are roughly H=96, W=64, and they can walk anything up to H=24, but at 32 they have to jump. A good Sniper ledge will be H=48. But I wander - do the same to all the bottom vertices until you have the following - be sure to SAVE INCREMENTALLY because you can not UNDO a VERTICE EDIT:

Now after that is done check the alignment of the RED BRUSH in all the views, and then go to EDIT/SELECT NONE. Do this before loading in any new texture packages or picking any new textures. Browse to STARSHIP/TRIM in the TEXTURE BROWSER (if you shut down the editor and then opened it for this lesson you'll have to reload STARSHIP.UTX). I'm using RIB and I suggest you do the same. Select it by clicking on it and then go to BRUSH/SUBTRACT. You should see a cube that has a big bottom and small top, and the texture will look all funky. In the 3D VIEW select each wall texture by pressing and holding CTRL when selecting each one. This will take some practice but you can do it - once all four slanted surfaces are selected go into SURFACE PROPERTIES/ALIGNMENT. Use.05 for the SIMPLE box and WALL DIRECTION for your alignment. Press APPLY once that is done and you'll see how neatly the texture fits now. Open up MINE.UTX (I like the lights here) after EDIT/SELECT NONE and browse to the LIGHTS sub-catagory. I'm using MLIGHT3 and I suggest you do likewise. Go into SURFACE PROPERTIES/ALIGNMENT and DO NOT ALIGN TO FLOOR! This is one of those rare exceptions I mentioned in Lesson 1. Instead select 0.25 over in the SIMPLE drop down box, hit apply and you'll see it fits perfectly. Go into the FLAGS tab while you are here (click slowly back and forth until you see a bunch of empty checkboxes) and select UNLIT:

Using the various grid views drag the light into place just under the newly created light source. I usually position it so it fits right on the edge of the nearest darker gray grid unit. Be sure that you get it as close as possible without any part of the little torch getting outside the room. Also be sure to center it perfectly. REBUILD, SAVE INCREMENTALLY, and PLAY LEVEL.

GOOD JOB EVERYONE! You just did something most mappers don't know how to do - you VERTICE EDITED. What you learned here will help you make shapes that you probably thought you never could. It does come with risks however, it can cause something called BSP LEAKS which will translate into a HOM (Hall Of Mirrors) effect in your level. Also if you forget to SAVE INREMENTALLY you may find you have to do a whole shitload of work over, as you can't UNDO a VERTICE EDIT. BTW the UNDO and REDO buttons are in the top toolbar - these are the two arrows pointing left and right. Anytime you mess up and move something you don't want to - press the button pointing to the left and it'll UNDO it. OK, in lesson 3 we're going to add some things to our room - feel free to add another PLAYER START or two and a weapon (ACTOR/INVENTORY/WEAPON/TOURNAMENTWEAPON) if you want to have a quick and bloody deathmatch against a bot. See you in Lesson 3!


Lights in the Unreal Engine

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The Unreal Engine uses light actors to show the player the environment as the designer wants us to see it. By default, there is no light in the environments that area created. Lights have to be added, and this is done via light actors.

A Light actor in itself is really a point in space, infinitely small, that emits light. If we see an environment that has a hallway, with bright lights set into the roof, it isn´t the textures on the roof, nor is it the brushes that are giving off the light, but in fact Light Actors placed into the hallway (with this example, most likely just below the supposed lights in the roof) to give the proper impression to anyone playing the game. A light actor can have many attributes set that allow the light given off to be of almost any style of brightness and color.

There are initially two different light types. The first (which is the default) is the static light, the second is a dynamic light. These initial types are explained further in more detail. These two light types contain many variables, and settings that are later explained.


Static Lighting

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

The Static Light in the Unreal Engine is a light that does not move. This has a double meaning, not only does the light itself not move from place to place, but the light that it emits is steady, and there are no other fluctuations in the light that is emitted. Static lights can be made to shed any color, and brightness, and though they can in fact affect moving objects in a dynamic manner, the light itself is restricted in what it will do. This light type is the most commonly used light type in the Unreal Engine, as it has much lower resource needs than a dynamic light.

Static lights can have certain effects placed on them, such as giving off light like a torch (in a narrow beam of light rather than the way that a normal light bulb gives off light). Static lights can also have a corona effect if desired, which may look like it is changing.

Static Lighting means that the light itself cannot move, that the light given off by it does not move and that it does not turn on and off.

Static Lights are placed like any other light type. (This is explained under the Adding Lights heading in this section of this file).


Dynamic Lights

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

Unlike Static Lights, Dynamic Lights can have many more effects, and can look much more interesting to a player. The catch however is that they require a lot more resources to be rendered, and may have a very detrimental effect on the framerate on lower end machines. This means that while pretty, they should be used sparingly, and certainly carefully.

Dynamic lights can move (by attaching them to a moving object) or they can flicker on and off, or they can give off a light in such a way that it appears to be sparkling, glittering or any mixture of the above. The light is initially placed in the same way as a Static Light but more settings need to be changed to create the effects. (This is explained under the Adding Lights heading in this section of this file).


Light Properties

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    Forward:

    I have just finishes the Light Color Tutorial, but there are so many more things that lights can do, so let's get into it.

    Abstract:

    Lights can do MANY wonderful things in Unreal, and to not know how to use them is a crime against yourself, as they add SOOOOOOO much depth to a level.

    Assumptions:

    I am assuming that you know how to create lights, change colors maybe and are familiar with the UnrealED interface.

    Tutorial:

    Introduction:

    There are a million things that lights will do for you in UnrealED, but I will go through a few of the better effects, and hopefully by the time you finish this tutorial, you will be able to get more out of lights, and the other effects that I have not listed here will be a simple click away...

    Watery Shimmer:

    When you have pool of water, adding this type of light will make it HEAPS more realistic. It makes the light "reflect" off the water and fill the room with a shimmering light. The picture will explain the settings of the light.

    Colored Lights:

    Colored Lighting will ALWAYS make a level more realistic, and I have included this simple light here as well. I have posted a full tutorial on colored lighting, and if you want more information about changing the color of the lights, please see that tutorial.

    Disco Lights:

    This type of lighting effect will work !!GREAT!! for a power generator room, or a "high pressure" type of environment. It will leave little gaps for people to hide in, whilst no making them invisible for others. This would be ideal for an "emergency" situation as well.

    Flickering Lights:

    Flickering lights add a great level of realism to a part of a level that is experiencing "power problems". It will also function well for a underwater light, as the water may have seeped through the insulation and may be causing the bulb to "short out". Once again, use is sparingly to add "eye candy" for that special part of a level.

    Search Lights:

    A search light will add great realism to a "get out of the prison" level, or make an "emergency" feel much more to the point.

    Strobes:

    A strobe will make play more difficult, as things will "jerk" from place to place as they are lit and hidden in shadow, but if used here and there, this will add a great "room" to your level.

    Sound:

    Yes, that's right, you can edit the sound property of your light. For example, in a "red alert" setting, you may want to have an alarm blaring. To do this, select sounds, then load a sound package (to do this, press the "three little dots" in the ambient sound box, and you will be show a sounds bar. Select load from the options at the bottom and load a sound package (like ambmodern) and choose the sound that you want played with the light.) When you have found a suitable sound for the occasion, select "use" in the light properties box (next to the three little dots) and rebuild the level.


Colored Lighting

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    Forward:

    I wanted to show everyone how EASY it is to have wonderful colored lighting in a level, and the best way t do that is to post a tutorial.

    Abstract:

    Colored Lights are simple, but you have to know how to do them first, so here goes.

    Assumptions:

    The only assumption I make here is that you can follow instructions... hehehe :)

    Tutorial:

    Introduction:

    Okay you have wonderful lights all through your level, but to add that little extra, why not make them all different colors as needed?

    Placing the light:

    I won't go into detail here, as you should already know how to place a light, but if you have somehow missed it, then all you have to do it right click where you want it (in the 3D view) and select "add light here" from the drop down menu.

    Setting the Color:

    Once you have added the light where you want it to go, all we have to do is set the color. Once the light has been placed, select it and bring up the advanced properties. Then bring up the "light Color" tab. Here you will find three setting. The first will determine how much light the light actually produces. The second is what color the light will actually make. The third sets how much saturation is in the color (how affected the area around it is...)

    Option One - The Light brightness:

    This one is pretty straight forward. The more brightness your light has, The brighter it will show up and brighten the area around it.

    Option Two - The Light Hue:

    Light hue means the color of light generated by the light. This is where the actual color setting is selected. It is as easy as entering a number for the color you want. Unfortunately, when making a map in the editor, there is no way to find out what color is selected by a particular number. (Well not really anyway). I have added a few colors and their numbers, to make life easier.
    Red = 0
    Yellow = 23
    Green = 64
    Blue = 128
    Purple = 192
    Red = 255
    The numbers are actually representing a color wheel (remember those things you made in primary school?), so as you get close to the end (255), you will notice the colors start to go reddish - until you get to 255 where the next color is zero again.

    Option Three - Light Saturation:

    Light Saturation basically means how the textures around it will be effected by the light color. The default setting is 255 - Which means the textures around it will reflect ALL the possible colors generated by the light, but to have nice colored lighting, a setting about halfway down the bar (127 - if you want a number) will allow you to generate any color that you like.

    Rebuild!!!:

    When changing any light setting make SURE you do a complete rebuild (include the "auto BSP" tab with the "Auto Lighting" tab as well) otherwise you will run into problems.


COLORED LIGHTING...

By: Silencer

utcity@planetunreal.com

FOREWORD:

In this tutorial, you will learn how to make colored lights such as that in CTF-Dreadlock and AS-Pyramid.

DIRECTIONS:

First go ahead and start up UnrealED. Now open up the Crypt2.utx texture set in the menubar. Scroll down a bit until you find a texture called 'Awall'. See below to view it:

Select the texture and then right click on the [image] cube button and click on Cube Properties. Enter the following numbers: 512 height, 1024 width, and 1024 breadth like so:

Then select on 'Build'. Now [image] add the brush to your world. You should then see something similiar to this:

Ok, now right click on the top of the cube (on the inside and in the center) and select, 'Add Light Here'. Now you should see a small torch-like thing. Right-click on that light and go into its properties. Under the 'LightColor' properties, plug in the following attributes:

  • LightBrightness - 120
  • LightHue - 250
  • LightSaturation - 75

See below for an illustrated view:

Now close the property menu and press the F8 key. Click on 'Rebuild Geometry'. You should notice your cube turn a red color. See below:

Now you have successfully created a colored light. For more information, such as changing to different colors, continue reading. Now, you're probably wondering how I knew that those three numbers above came out to be red. Well, what I use to find out certain colors is the color wheel thing or whatever it's called. Anyways, to find out different hue numbers for different colors, create a ZoneInfo in your level. Go into its properties and into the ZoneLight property. Now near the FogColor attribute you should see a black line with a little button on the right with three dots, click on it. The thing that pops up is the color menu.

Right now all your paying attention to is the colors and the little box on the bottom called Hue and a number next to it. I have decided that I want to change my color to blue. So I move my mouse onto a blue looking color and see that the hue number says 162. See below:

Now that I know what my hue is going to be I close the Color box and the zoneinfo properties. Then I again go into the Light properties and this time set the LightHue attribute to 162. Then I close the properties box and press F8 and rebuild geometry, and this is my result:

There, now you know how to change colors.

CONCLUSION:

Once again, I have started what I think an easy to make tutorial and have found it more difficult to explain, so if you have any questions email utcity@planetunreal.com. You should now know how to create colored lights and change them. Try experimenting a bit with different colors to see how they look. Also, you can do this same technique with coloring fog. If you would like to see and example of colored lighting in a level, download CTF-Dreadlock and take a look at the bases inside.

OTHER:

For comments/questions email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


Colored Lights

By: Verxion

jc83151@goodnet.com

    FOREWORD:

    Installment number 2. I decided to do colored lighting next since it is so gosh darned easy! :-)

    ABSTRACT:

    This tutorial will go over colored lighting, and how it is done within Unreal. Colored lighting is really quite simple to do. Just remember, don't go nuts with colored lighting or you can overwhelm people. :-)

    ASSUMPTIONS:

    You know how to make a room, put a playerstart in it, how to move and shape your brush, and deal with textures. Additionally, you should know how to place a light. If you don't know how to place a light, try rightclicking on a view window. :-)

    TUTORIAL:

    The first thing you need to do is make a test room. Make this one fairly large so you can have lots of different lighting in it. I leave it to the student to know what "fairly large" means. :-)

    Well, I have been thinking of the best way to show you guys how to make colored light. Since all I am really covering is how to make a light have color, this assumes you already know how to create a light in the first place. What I will do is show you how to make a room with some cool colored light, that has some cool lighting effects that are darned simple to do.

    Since you made a room, you must know how to size your brush. Well, size your brush so that it is fairly small. How small? Well, how about 25x25x25 or so. Hopefully you can fit several of these into your room. Arrange three of these cubes on the floor as shown below:

    caption: here, you can see 3 cubes on the floor, waiting for colored light to "happen". :-)

    caption: These are the same 3 cubes on the overhead (xy) view.

    See the note at the bottom of this tutorial now. It is very very important to helping you understand the rest of the tutorial, but it is kindof off of the real topic at hand. If you already know what Hue and Saturation are, you probably will only want to glance at the important note after going through this tutorial.

    ***Go read the important note, then come back to this part of the tutorial***

    Now, place a light in between the three cubes, at a height halfway up the cubes. Right click on the light, and choose "properties". Now, under the properties, choose "LightColor".

    caption: This shows the LightColor section of Light Properties.

    Now, hopefully, you know what Hue and Saturation you want. Place the values you want in those two spots. If you don't see the color you expect, lower your saturation value, and it will VERY VERY likely fix your problem. If you don't have a specific color in mind, we can choose values of 200 for brightness, 30 for the hue, and 64 for the saturation. Now, make certain that this one light is the ONLY light on your level, and do an F8, rebuild, then ctrl-p and take a look at it.

    Now, change the value of the hue to each of the following values: 230, 163, and 100. You can see quite clearly that the Hue value walks you around the color wheel.

    caption: Sample of how the colored lighting can look.

    Well, you are now off on the great road of color! Use the force wisely, for it can corrupt the soul, er, um, nevermind. :-)

    Good Luck!

    IMPORTANT NOTE!!!:

    Ok, at this point, we are going to make a diversion from an otherwise perfectly normal tutorial. :-) One of the reasons colored lighting can be so difficult for people is that 99% of it is done "blind". You just type in numbers and try the level. This is VERY tedious. It turns out that inside of UnrealED there is a place that has the colors, and they are labeled. But this area isn't available while you are editing light colors. A poor design decision. What I am going to do here is show you how to get to this color area. Once I have done that, we will resume the tutorial. If you don't already have a "zoneinfo" on your level, make one (it is in classes -> Actor -> Info -> ZoneInfo). Inside of ZoneInfo, choose "ZoneLight", and click on the black color bar next to "FogColor". Now, to the right of the black color bar, you will see three dots in a button. Click on this button.

    caption: This is the ZoneInfo Properties area that leads to the color chart.

    caption: This is the color chart itself.

    Ok, now you should see all kinds of colors. To my current knowledge, this is the ONLY place that allows you to see colors in a chart like this in UnrealED. Important things to note when looking at this chart is the block of color, the slider to its' right, and the text entry boxes under the color block. The important text entry boxes are "Hue", "Sat", and "Lum".

    You can click in various different spots in the color block, and the values in the entry areas will change to reflect the color you have chosen. To the right of the color block, is a small slider that lets you adjust the "brightness" of the color, and this value is reflected in the entry marked "Lum". The color you are creating by using these tools is shown in the "Color|Solid" area.

    PLEASE understand that this color chart is intended to be used to adjust that fog color I showed you earlier. This tutorial is about colored lighting, and we won't be dealing with fog right now. Therefore, I am just showing you this area since it will allow you to visually see what "Hue" and "Sat" you want for your colors.

    Ok, return to the previously interrupted tutorial. :-)


Lens Flares

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    Forward:

    There seems to be a great big huge whopping demand for this tutorial, so here it comes.

    Abstract:

    This tutorial will show you how to add in Lens Flares into your lights. It will also show you how to change them so that they look the best for your level.

    Assumptions:

    I assume that you already know how to make lights, and how to place them in your level. If not, you should have a look at the lights tutorial I have written.

    Tutorial:

    Introduction:

    When you have placed you lights in the level, you will need to open up a new texture package for the lens flares them selves. To do this make sure you are browsing the "textures" in the right hand bar, and click on "Load". When the dialog box appears, open the GenFX.utx package, and you should see all the possible textures that are there.

    Selecting the Flare:

    When you find the light that you want to have a flare on, bring up it's "advanced properties" by right clicking on it, and then go to the Textures bar. Choose a texture that will suit your room, and click on it. Then go back to the Light Properties, Choose DISPLAY>SKIN and you should see a little Input there. Press the "use" button and your new texture's name should appear in the box.

    When that is done, go to LIGHTING>BCORONA and set it to "true" (defualt is "False")

    Adjusting the Size of the Corona:

    You can at this piont rebuild your level (AutoBSP and Lighting) but your flare would probably be way too big to look good. Let's fix it to be the right size eh?

    Select the Light Properties again, and choose DISPLAY>DRAWSCALE. The defualt here is 1.00000 but you will probably want to have your one set between 0.3000 and 0.5000 (Hell, I am guess how big you want it here. :)

    Lastly:

    There is just one more thing I think I have omitted so far... In the Light Properties, you have to change a few settings. Select LIGHTING>BCORONA and set it to true, otherwise your Flare won't be visible, and there is another setting there called bLensFlare, but that one doesn't seem to do all that much, so you might just leave it set to "False".


Wolf's Basic Light and Texture Tutorial - A Beginners Guide to UnrealEd

Wolf's Tutorials: Light and Texture

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Introduction

To start with I am assuming you have a basic knowledge of UnrealEd and have read my BASIC tutorial or something similar. This tutorial is designed to get you started with basic light and texture procedures and will not go into great detail on either. The tutorial will give you enough information so that you can start doing cool things with light and textures, but it is not THE ONE document on the subject. If you are a seasoned veteran in UnrealEd then this tutorial will not help you much. If you are just starting or there are things you aren't sure about with lights and textures then read on!

Getting Started

First of all, to get the most out of Unreal, make sure you have the latest patch available at Unreal.com.
Second, if you have any problems starting the editor then get the latest UnrealEd fix here.
Third, To get the best performance out of the editor, limit what you have running in the background. Remove everything unnecessary including the screensaver to get maximum performance from Unreal and the editor. UnrealEd is a memory hog.

Tip: If you have been running a lot of games or other CPU resource sensitive applications, then reboot your system. This will help clear virtual memory and RAM and will allow maximum performance from UnrealEd. The more memory you have free, the less chance of a "random crash."
Last, If you have been a Quake/Quake2 editor and are trying out UnrealEd then it might be helpful to read this article: Making the Change.

Lights and Textures

Good lighting and proper texture can make or break a level. I have played lots of levels that I thought, "With the right lighting and better texture alignment, this level would ROCK!" All too often amateur level designers neglect proper lighting and texturing and effectively "ruin" their levels.

Texture Packages

Like most things in Unreal, the textures are stored in package files with the extension .UTX. Theses packages will be loaded with the maps but are not stored in the maps. When you load a map in the the editor it will only load the textures from the pack that are used in that level. To get the whole texture pack loaded you must click the LOAD button on the bottom of the Browser window and select the appropriate .utx file. This is the Texture Browser and the the texture with the green box around it is the highlighted one. This is the texture that will be put on any brush you add.

In most of the texture packs that ship with Unreal the textures are grouped by the texture application. That is, Lights, Walls, Floors, Ceiling, etc... are grouped together.

In the image above Certain parts of the browser window are numbered. Here is the key:
1) Selects Browser Mode (Textures, Classes, Sounds, etc....)
2) Selects already loaded texture packs. the arrows [image] will scroll through the texture packs.
3) Selects the groups within the texture pack.

The buttons

1) Scrolls through the groups in the current texture pack.
2) Shows the textures one Texture wide in the texture window.
3) Shows the textures two Texture wide in the texture window.
4) Shows the textures four Texture wide in the texture window.
5) Selects All groups in the current loaded texture pack.

Getting Started

To begin with open the editor (duh!) and choose a texture pack. Choose something that has light textures in it. I am using DecayedS so you might want to load that pack to follow along. Now pick a base texture and build a room with the cube brush, make it 256 high by 512 by 512. To change a texture on a brush face simple click it in the 3D view to highlight it.

Once a texture is highlighted, choose another texture in the browser and click it. This will change the highlighted texture to the one you just picked. Try it a couple times. Good. OK, now we want to change all the walls to a different texture. To make multiple selections hold CTL while clicking it. Also, when making multiple selections, if you hold CTL and and click a texture that is already selected it will "un-select" that texture.

Hold CTL and select all the walls then go to the browser and pick a nice wall texture to change it to. Click this texture in the browser and all the walls should be re-texture now. After making multiple selections and re-texturing it's a good idea to click the "Select None" [image] button to make sure you don't accidentally retexture something again. I usually click this button out of habit before selecting a new texture, just to make sure.
Okay, now that you know how to change a texture, go ahead and change the floor and ceiling.

Tip: You can select all the visible textures on a given brush by highlighting one texture on the brush and then pressing SHIFT-B to select them all.

Now that the room is textured, we need more area to work with. Copy* the room and move the brush just to the "north" (one grid square) of the first room in the overhead view. Now subtract the brush and you should have two identical rooms.
We are going to make a window between the two rooms. We are going to make this window 128 high and 128 breadth. We know that the two rooms are 16unitss apart because we placed the new room 1 grid square from the first one (one grid square = 16 units). So we need to make this window 16 units wide to fit between the two rooms.
So right-click the cube icon and go to Cube Properties. Make the cube 128h x 16w x 128b and then position it between the two walls.

I know what you're saying....."Wolf, I can't get the damn brush to line up correctly between the two rooms!" I planned this to show you something :-)

To get the brush to line up correctly you can do two things: a) you can right-click and empty spot on the grid and then resize the grid to 8 units.
b) you can highlight the red brush by clicking it, and then right-click one of the "corner" vertices and the brush will "snap to the grid" using that vertex. UnrealEd snaps by the "pivot" vertex (center vertex by default). The "pivot"vertexx will have a little cross on it.

Once you have the brush lined up right Subtract it. You should now have a nice square hole between the two rooms.

In casee you didn't read the BASIC tutorial (you should have!) then here is how to copy the room: Move the red brush just off the room in the overhead view. Now click one side of the first room brush. This should highlight the brush. Right-click and go to Copy Polygons To Brush. This will make the red brush an exact copy of that brush. Now click anywhere in the window or click the Select None button. Move the red brush to it's new location and click subtract. You have just made a copy of the first room!

The Window

We aren't finished yet. Yes, we have a hole, but we want an actual Window there. First step is to find the Window Texture we want. There are some good ones in the Genln.utx pack so go to the browser and load that pack, then go to the Glass group. Click the Select None button (just to be sure) and then select a nice glass texture and highlight it.
Now right-click the sheet Icon. We know the size is 128 x 128 (the default) so we shouldn't have to change that, but we do need to change the sheets orientation. Right now it's set on the Floor/Ceiling, so we need to click the Y button. That should make it right. Now position the sheet just in the center of the "hole." Now to place it correctly you will have to resize the grid, so if you used the "pivot point" method to place the hole then resize the grid now to 8 units. Now place the sheet right in the center of the hole.

Once you have the sheet positioned then click the ADD SPECIAL Icon. Go to the Predefined drop-down menu and select Transparent Window and under Visibility click the 2-Sided button. Now click the Add Special button and you should have a window.

Tip: Most brushes in Unreal will be 1-sided. We made the window 2-sided because we want to be able to see it from both sides (from both rooms).

Collision

If we were to play this level now (aside from the fact that it would be totally dark since we don't have any lights) you would notice that you can shoot and actually move through the window. This is normal. The sheet brush we used to add the window will NEVER block objects. EVER. Sheets do not, and cannot block anything. Don't bother messing with the Collision Properties of the sheet, it won't help.
However, we do want this window to block objects, so lets figure out how to do that. UnrealEd is cool. The programmer knew that since sheets won't block anything there needs to be a way to stop objects from moving through sheets. We are going to use an INVISIBLE COLLISION HULL. Basically a collision hull is an invisible cube brush used to block actors but cannot be seen in the game.

Rules: 1) Invisible Collision hullscannott touch other geometry.
2) See rule one.

We need to place our collision hull just in front of the window, but not touching it. I usually make my collision hulls one unit thick. Since the collision hull cannot touch anything else, and we want it as close to the window as possible, let's size our cube brush so it is just smaller than the window and 1 unit thick (That would make it: 127 x 1 x 127). So size the cube brush like that and then place it just in front of the window and then click the AddSpeciall Button. From the Predefined menu choose (oddly enough) Invisible Collision Hull. Add one on both sides of the window. After you place them both, if you zoom in a bunch it should look like this in the overhead view:

Note: if you look in the 3D view you will see the invisible collision hulls. Click thereal-timee Updating button (looks like a joystick) in the 3D window and it will disappear.

Okay, we have done a little work so it is time to save it. First press F8 and click Rebuild Geometry. Use all the default settings. You should notice that everything went black in the 3D view. This isbecausee we have no lights! Choose the "Textures" mode to get a "full bright" view in the 3D window. We will add lights soon. After rebuilding then save the map (call it anything you like).

NOTE: There are other methods of adding windows and getting collision without using sheets and collision hulls. These methods use very narrow cubes with a transparent window texture on the visible faces. This tutorial will not cover these methods, as they are more advanced.

You will probably want to change the texture on the "hole" the window sits in. The easiest way to do this is to select one face of the hole, SHIFT-B to select the whole brush and then choose a new texture. Pick a trim texture or something that looks like a window frame. You will probably have to play with the alignment to get it to look right.

Texture Properties

There is a lot to learn about texture properties. There is a section in my basic tutorial about texture properties and alignment and if you haven't read that yet go do so! The following tips and tricks expand on that and will give you a good idea what the different properties do. This is the Surface Properties window for a texture. I will NOT outline each item, only the most commonly used types.

MASKED - This will "mask out" or hide the color 0,0,0 (usually black by default) in the color palette of a texture. This is used on grates, fences, screens, and stuff so you can se through part of it. There are several textures in DecayedS (under Mask) that you can add to a sheet somewhere in the level to look at it. They are Masked by default. Delete the sheet when you are through looking at it.

INVISIBLE - This will make any surface invisible in the game. Used on Zone Portals andCollisionn Hulls.

2-SIDED - Makes the face of the brush viewable from both sides. Should only be used on sheets (for now) because you will never see the "inside" of a solid brush.

PORTAL - Makes the surface a portal for zoning. Used on water/lava/slime, etc...and the invisible zone portals used to "zone off" your level.

MIRROR - Should be self-explanatory. Makes a reflective, mirror surface. Used with Translucent you will get a polished, reflective effect.

SPECIAL LIT - This surface will only be lit by lights that are set up as Special Lit lights.

UNLIT - This surface will not reflect light and will always be lit 100%, regardless of lights.

HI/LO SHADOW DETAIL - Increases or decreases the amount of shadow detail on the surface. Checking both of these boxes sets a special "Medium detail" flag.

BRIGHT CORNERS - This will "amplify" the light refracted by the surface. Useful for lighting those "hard to light" areas and forincreasingg the brightness of the surface for lights and other textures.

TRANSLUCENT - This makes the surface "see through." It partially "masks out" the darker colors in a texture. The "more black" the area, the more translucent it becomes. Used on water, glass, etc...to get a surface that you can partially see through.

MODULATED - This works like translucent only in reverse. The lighter the texture color the more it is masked out. Look at the texture pack Detail.UTX and add a sheet and set it to modulated and rebuild to see the effect.

Big/Small WAVY - This will cause the texture to kind of sway. You would use this on water or for other moving effects.

FAKE BACKDROP - This tells theenginee to not draw this texture, but to "display" the skybox here.

U/V-PAN - Will cause the surface to "move" in the U or V direction. Used for simulating movement on water,conveyorr belts, etc....

Texture Alignment

I could write a book on texture alignment, but basically all you have to know is that "if it looks right it is right." If you add a texture that doesn't line up on your brush, people notice. Reviewers take points off, and professionals laugh. Line up your textures!
The easy way to align them is by highlighting the texture and right-clicking and selecting one of thealignmentt settings. Floor/Ceiling is for horizontal surfaces and will help you tile your floors/ceilings correctly. Aligning as Wall aligns vertical surfaces, and Wall Panning will help you align multiple wall surfaces so the tile correctly as well. You can also access these alignment settings in the Surface Properties Window by clicking the Align tab. Again, the best way to learn this is to try it your self and see what you get.

Panning

Panning (accessed through the Surface Properties Window, Pan tab)will move the texture left, right up or down so you can align them "manually." You can pan textures by clicking the Pan Textures on the ToolBar [image]. Hold CTRL and left or right mouse to move the texture in different directions.

Rotation

You can rotate the textures in the Surface Properties Window, Rotate tab. The buttons there are pretty self explanatory as to which way they rotate the textures. You can also rotate textures "manually" with the Rotate Texture button [image] and holding CTRL and left or right mouse button.

Scaling Textures

Often times you will need to scale your textures, either up for large surfaces or down for smaller ones. Click the Scale tab in the Surface Properties Window. Simple scaling will scale the texture uniformly in all directions. Using the Custom Scaling settings you can scale itdifferentt amounts on the U or V axis. Use this wisely, as you can really distort a texture with it.
Tip: Scaling a texture too large can also make the texture look really pixelated and "fake".

Add Lighting

Okay, you should have a good idea what you are doing with Textures now, so we will have to add some lights to the level. If you added any sheets or anything to play with the texture properties remove them now. Rebuild and let's light this baby up!

The easiest way to add a light to the level is to right-click the 3D view where you want the light and from the menu choose Add Light. Easy enough? You can also hold the L key and right-click the map to place a light where the cursor is.

Okay, we had the two rooms and the window, so lets light it up some. First add a light in the center of the ceiling of one of the rooms. Rebuild and switch the 3D view toDynamicc Lighting. Now add a light in the second room. Rebuild and save.
With the lights right up against the ceiling it doesn't really light the room very well. Select both lights and lower them about 64 units. Rebuild again and look at the difference. If you want to see a "side-by-side" comparison, only lower the light in one room.

Now we have to add a light source. One thing that bugs me (and most map reviewers) is when you have a lightemanatingg from nowhere. That is, a nice light area with no light source to emit it.

For this tutorial I don't want anything fancy so I will add a plain square light on theceilingg. You can and should get more creative with your lights. First go to the Light group in the texture set and find one that is appropriate for a ceiling light. I used Light6 at the bottom. Now size the cube brush to 16 x 128 x 128 (or whatever is appropriate for the texture you selected) and place it on the ceiling like below.

Add the brush and texture the lower face with the light texture you chose. It should look like this:

TIP: to reduce the BSP cuts and thereby reducing your poly count add the light fixture as a SEMI-SOLID brush. It won't matter much for the simple level in this tutorial, but it will help a lot in larger, complex rooms with lots of polys.

We are going to have to lighten up this light some to make it look right. If you don't believe me then rebuild now and look at it. It doesn't really "glow" enough to be giving off the light does it. We are going to try two things. Okay,highlighth the light surface of the texture and right-click and open the Surface Properties window. Check the Bright Corners box. Close the window, rebuild and now look at the light. Now go change the surfacepropertyy to Unlit and rebuild and then look at it. The images below illustrate these effects:

Normal, BrightCorners, Unlit

Now, by using Copy Polygons to Brush you can make an exact duplicate of your light fixture by copying the size and textures to the red brush, move it to the other room, and adding another one. Do this now and then rebuild and you will have a light fixture in both rooms.

Before we move on to all the light properties, you should play around with the surface properties a bit. Change one of the floors to Mirror and Translucent, rebuild and look at it. Then Make the other one Special Lit and rebuild. See how it's dark. That'sbecausee a special lit texture will only reflect a light set to special lit, and we have none in our test level. Change the light in that room to Special Lit and then rebuild. Notice how everything else went dark? Okay, reset the light and the textures. Play some more, set a floor to Hi or Lo shadow detail and look at that. Try making setting it to Bright Corners. Play with all the settings we outlined above to see what they doexactlyy. You should get an idea of what each property does and an idea of when and where to apply them.

TIP: DO NOT make atextureetranslucentt unless there is something behind it to show through. If you made a floor for instance translucent and there was nothing below it but the void, well try it and see what you get!

Light Properties

If we open the light properties window you will see all the basic properties you do for every actor, but the ones most important to us for this tutorial are under LightColor and Lighting.
There are four settings that we will use most often and they are the three under LightColor:
LightBrightness
LightHue
LightSaturation

and under Lighting:
LightRadius

LightBrightness is just that, how bright the light is from 0 to 255.

LightHue is the color of the light. This can be fun to figure out at first. If you have trouble finding the right light color values try Ulight, a wonderful utilityavailablee at my web site (http://unreal.gamedesign.net). It uses Windows color picker and allows you to select the color and then gives you the Unreal color values forBrightnesss, Hue and Saturation. A basic color chart would show:

  • Red=0
  • Orange=25
  • Yellow=50
  • Green=60
  • Blue=150
  • Purple=190
  • White=255

LightSaturation is the amount of light that is reflected off a surface by color. The higher the saturation, the more colors it will reflect. 255reflectss all colors, effectively making the light white. Remember, the amount of saturation can affect the color of the light.

LightRadius is how far the light shines from it's source. Setting this correctly for the area is crucial to getting the right light effect in your level. Play with this setting a lot to get an idea of exactly how far the radius extends. it can also be helpful to select the Radii view in the 2D windows and select your light. A Redcirclee will appear around the light, indicating it's radius.

(note: LightRadius is set very low for this example image)

Dynamic Lighting Properties

Lights in Unreal have quite a few settings to get dynamic lighting effects. It isbeyonde the scope of this basic tutorial to outline each one. You set these with LightEffect

and LightType

The best advice here it to try them out and see what they do. Remember to turn "real-time" updating on in your 3D view to see the light effect in the editor.

Tip: Too many dynamic lights in one area can slow your levels down, as they can take quite a bit of your PC's resources to render. Use sparingly.

Coronas

(LensFlares)

Although there is a setting for it in the actors properties, Unreal has no true Lensflare effects. It does, however have coronas which can look awesome when used correctly. I will give you the basics on creating the coronas and then you can experiment to see what looks right on your particular light in your particular level.

To start with we need to pick a corona texture. There are some good ones in the GenFX.utx package. Load it now and go to the LensFlar sub group.

Pick one you like and click it to highlight it. Now pick a light in your level, and right-click it. Under the Lighting Properties set bCorona to true.

Expand Display and then click where it says Skin. Click the "use" button and the texture name should appear next to it.

Rebuild your level and should now have a corona on the light.

Note: if you do not see the corona in the editor go to Options on the menu at the top of the editor and then Preferences. This opens the Advanced Options properties window. Expand Rendering and then Software Rendering. Set Volumetric Lighting to true.

Tips and Tricks

Drawscale (under Display) will set how large the corona is. Most likely the default setting of 1.000 will be too large and look "funny." Scale it down. I use .2 or smaller most often.

The LightRadius will set how far away the corona is visible from. The farther you are from the corona the bigger it will appear. As you get closer it scales down. Setting the Light Radius affects when the corona comes into view.

When using colored lights with coronas I will often use two light actors. I set the light brightness to 1 for the light with the corona and then add another light with the actual settings I want the light to give off, and place it next to or under the corona light. That way I can set the LightRadius of the corona so it will look right, and still get the proper LightRadius for the light that will actual light the area.

This concludes the tutorial. If you have any questions, you can e-mail me through my site. You should have enough information now on the basics of lighting and texturing to get started. Make a test level or two and play with what you have learned. Use of dynamic light and textures can really enhance a level.

Good luck and happy mapping! -Wolf Wolf@gamedesign.net

©Copyright 2000 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


Creating LensFlares

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: tyleraperry@juno.com

Date: Friday, December 22, 2000

Forward:

One day, after some hard work of trying to figure out how to create a good looking lens flare, I decided to write it all down.

Abstract:

This tutorial will go over how to create a good looking and realistic lens flare that will liven any flame, or industrial scene up.

This tutorial will also teach you how to size up the draw scale of the lens flare.

Assumptions:

I assume you know the basics of the editor, including creating a room, adding a light to it, and loading textures.

Tutorial:

Introduction:

Lens flares can add a lot of detail to your level without really causing any memory loss or a noticeable decrease in framerates.

Creating the Flare:

Start out by creating a room about 512x512x512 and add a light directly in the center of the room. Good. Now, open up the texture package GenFX.utx, this package holds around 99.8% of Unreal/UT’s total amount of lens flares. Select a lens flare that suits you. Select your light and bring up its advanced properties, then expand Lighting. Now change bcoronas to true. Now, you probably think that creating a lens flare was easy, well you aren’t done yet. (Don’t mess with blensflares, it doesn’t work). Expand display, then select skins and click use. Now you have a lens flare! Check it out in the editor.

Setting the Lens Flare Size:

Now that you have your flare created, take a look at it, it is way too big for comfort! Expand displays on your light and change the DrawScale of the light to around 3.5 for the average light, to whatever suits you. Creating lens flares is simple! =)

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


COLORED LIGHTING...

By : Matt Murphy utcity@planetunreal.com UT City

FOREWORD:

In this tutorial, you will learn how to make colored lights such as that in CTF-Dreadlock and AS-Pyramid.

DIRECTIONS:

First go ahead and start up UnrealED. Now open up the Crypt2.utx texture set in the menubar. Scroll down a bit until you find a texture called 'Awall'. See below to view it:

Select the texture and then right click on the [image] cube button and click on Cube Properties. Enter the following numbers: 512 height, 1024 width, and 1024 breadth like so:

Then select on 'Build'. Now [image] add the brush to your world. You should then see something similiar to this:

Ok, now right click on the top of the cube (on the inside and in the center) and select, 'Add Light Here'. Now you should see a small torch-like thing. Right-click on that light and go into its properties. Under the 'LightColor' properties, plug in the following attributes:

  • LightBrightness - 120
  • LightHue - 250
  • LightSaturation - 75

See below for an illustrated view:

Now close the property menu and press the F8 key. Click on 'Rebuild Geometry'. You should notice your cube turn a red color. See below:

Now you have successfully created a colored light. For more information, such as changing to different colors, continue reading. Now, you're probably wondering how I knew that those three numbers above came out to be red. Well, what I use to find out certain colors is the color wheel thing or whatever it's called. Anyways, to find out different hue numbers for different colors, create a ZoneInfo in your level. Go into its properties and into the ZoneLight property. Now near the FogColor attribute you should see a black line with a little button on the right with three dots, click on it. The thing that pops up is the color menu.

Right now all your paying attention to is the colors and the little box on the bottom called Hue and a number next to it. I have decided that I want to change my color to blue. So I move my mouse onto a blue looking color and see that the hue number says 162. See below:

Now that I know what my hue is going to be I close the Color box and the zoneinfo properties. Then I again go into the Light properties and this time set the LightHue attribute to 162. Then I close the properties box and press F8 and rebuild geometry, and this is my result:

There, now you know how to change colors.

CONCLUSION:

Once again, I have started what I think an easy to make tutorial and have found it more difficult to explain, so if you have any questions email utcity@planetunreal.com. You should now know how to create colored lights and change them. Try experimenting a bit with different colors to see how they look. Also, you can do this same technique with coloring fog. If you would like to see and example of colored lighting in a level, download CTF-Dreadlock and take a look at the bases inside.

OTHER:

For comments/questions email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


Static Lighting

By: Dylan T. Gladstone e-mail

Unreal Map Designer's Diary

Lighting 1 - The Basics of Static Lighting
(You can download the map used in this tutorial by clicking here.)

Lighting plays as great a role in defining a map's atmosphere as does its physical design. Learning effective lighting techniques in UnrealEd is difficult because of the bewildering number of options available to the designer. I'll start out assuming that the reader has little experience with lighting and for this first tutorial, I'll concentrate on the basics of static lighting. Later on I'll get into dynamic lighting, and finally special effects lighting.

Static Light Basics

A static light in Unreal is one that doesn't change over time. Static lights are able to properly cast shadows, they won't pass through walls, and they don't hurt the frame rate at runtime. Since a static light will never change during the game the editor can pre-calculate how the light will look, enabling more realistic lighting and removing the burden of rendering the light from the runtime engine. This happens during the raytracing phase at the end of a map rebuild.

We'll start by exploring the properties of the default light in UnrealEd. First, create a room roughly 512 x 512 x 512. I texture mapped it using some of the brighter textures from the SkyCity set so the shadows will show up better.

Next we're going to throw in some columns to create more interesting shadows. I built four columns 512 units high, with an outer radius of 32 and an inner radius of 32 - 16. Each column has 8 sides.

Point the camera in the 3D preview window up to the center of the ceiling. Right-click in the center of the ceiling panel and select "Add Light here" from the pop up menu. You should see an icon of a torch appear roughly in the center of the ceiling. If you want, you can use the three 2D views to precisely locate the light just under the center of the ceiling.

Rebuild the map by pressing F8. Make sure the 3D view is set to dynamic lighting in the mode menu and your screen should look something like this:

Notice how the pillars cast shadows pointing away from the light source. This is calculated during the raytracing phase. As much as possible you should light your scenes with static lights. They look much more realistic and don't tax the rendering system as dynamic lights do.

Put in a player start at this point so you can check the scene from within the game engine. (Also don't forget to rebuild and save the level!)

(Click on the image to view full size.)

This shot illustrates one of the most common lighting mistakes you'll come across, a light with no apparent source. This is a subtle but effective way of detracting from the realism of a scene. Unless you're going for a special effect every light in your scene should have an apparent source of origin. This doesn't always mean a lamp. You can simulate light reflected off a pool of water by placing colored light sources directly above the surface for example.

Placing a mesh lamp on the ceiling solves the problem. While I'm on the subject of lamps, watch out for the mesh object "Lantern". By default it emits light. When building DM-Cycladic I didn't realize this and I doubled up on the lights in one of the early versions by adding light sources to lamps that were already emitting light. "Lantern2" isn't lit by default but you can cause it to emit light just like "Lantern" by altering its properties.

When working with lights it's sometimes helpful to turn on radii view in the actors menu for each editing window. Then when you select a light source you can see the maximum extent of the light's influence. The radius of a light is the area it will light if it's set to its maximum brightness. The default brightness of 64 only covers ¼ of the area.

Select the torch, right-click it, then set the brightness setting under the LightColor menu to 255. After you rebuild the map it will look pretty washed out in the 3D window. (You wouldn't normally use a light this bright indoors.) Try playing the level to see the effect.

Next, leave the brightness set at 255 and try experimenting with the light's radius. (Use the setting "LightRadius" under the Lighting menu in properties.)

Tip: Once you start lighting a large map it gets tedious rebuilding it just to check your lighting. If you haven't altered the geometry since your last full rebuild, just click the "Lighting" tab in the rebuild dialog and hit "Apply Lights". This starts the raytracing stage without going through a geometry / BSP cycle.

Now set the light's brightness and radius back to the default values of 64.

One frustrating aspect of UnrealEd is dealing with color. Instead of a simple RGB (red, green, blue) system, or better yet a visual color picker like in Photoshop, the color system in the lighting properties consists only of a hue and saturation setting.

The saturation controls how strong the color is. If you leave it at 255, every hue will show up as white. To see the effects of the hue setting, set the LightSaturation value to 128. Make sure the 3D editing window is set to dynamic lighting, then try dragging the hue slider around. Each time you let go of the slider, you'll see the color of the light change. You don't need to raytrace the scene to see the effect. Once you get a color you like, start playing with the LightSaturation setting.

Coronas

One of Unreal's most dramatic lighting effects are coronas. I'm sure you've noticed the bCorona setting in the lighting properties dialog. Just setting this to "true" has no effect. You also have to tell Unreal which texture to use as the corona's shape.

To illustrate the effect of the corona better I'm going to add a large room off to one side of the map so we can see the corona appear and disappear behind the columns. Create a brush 256 units high and 1024 units in width and breadth. Then align the brush so it's just touching one side of the first room and aligned with the floor. Cut out the room and texture map the walls and ceiling to match the first room.

Rebuild the map and you should end up with a structure that looks something like this:

Reset the light back to it's default color values, (brightness 64, hue 0, saturation 255). Then go into the lighting properties and set bCorona to "true". Then expand the "display" tab in the lighting properties. You should see a setting marked Skin currently set to "none". Load the GenFX texture set, then select the LensFlar group. Click on the texture map you'd like to use (I used #6), and then once it's selected, click on the "none" in the skin setting. Click the "use" button to set the texture of the skin. Rebuild the map, then try playing it. You should see the familiar corona effect in action.

(Click on the image to view full size.)

When using coronas it's a good idea to use the radius view as described above. The outer perimeter of the radius marks the point at which the corona effect becomes visible to the player. Experiment with a smaller radius in the map to see the effect.

To alter the size of the corona use the DrawScale setting in the display tab. Changing the ScaleGlow setting seems to have no effect on coronas.

Hopefully I've given you enough to get started with static lights. Future installments will cover more advanced topics such as the SpecialLit setting, dynamic lights and fog effects.

If there's any lighting feature in particular you'd like me to cover, please drop me an e-mail.


Static Lights 2

By: Dylan T. Gladstone e-mail

Unreal Map Designer's Diary

For this tutorial I'm going to delve into some of the more exotic types of static lights available. To illustrate more complex techniques, I'm going to require more complex structures. Since this isn't a construction tutorial, I've pre-constructed the basic map. You can start by downloading it here. Right now it has basic lighting just so you can see the structure.

You can see that just throwing in a few static lights creates a pretty bland environment.

The first step is to decide which texture maps you want to appear to emit light. The lava certainly should be a light source so right click on it, select Surface Properties from the pop up menu, and check the Unlit box in the dialog. Rebuild the lighting and play the map. The lava should be looking a little more like lava now. (Remember since we're not changing any geometry there's no need to rebuild the geometry or BSP. In the Rebuilder dialog click the lighting tab, then select Apply Lights.)

Delete the all the lights and rebuild the lighting. It's time to light the lava properly. Put a light anywhere in the hallway and make sure the 3D view in the editor is set to dynamic lighting, so you can adjust the color to match the lava. I used 20 for the hue and 0 for the saturation.

Now it's time to place the lights evenly over the surface of the lava. (Wouldn't it be nice if the lava texture could emit light? I've tried, but it doesn't seem to work properly.) Since there are no other lights in the map yet, we can save ourselves lots of time by jotting down the hue and saturation of our test lava light, then just right click on the lava texture and keep adding normal lights. Next right-click any light and select "Select all Light actors." Now right click a light and select properties, then set the hue and saturation for all the lights at once. If you rebuild the lighting now you'll find that the scene looks very washed out. Keep experimenting with the brightness setting for the lights until you get a deep glow over the entire surface of the lava. I ended up using a brightness setting of 10.

I've placed fluorescent light textures around the map. They're all based on the same fluorescent panel texture, with the ones applied to the inside of the ring structure on the ceiling of the circular room scaled way up so they appear to be solid white. Since they're all the same textures, just right click on any one of 'em then choose Select, then All Matching Textures. Right click on one of the selected textures and set its properties to Unlit just like we did with the lava.

Left click on a fluorescent panel to select it, then right-click and add a light. Repeat for each panel in the map. In the hallway, you should add several lights along each panel. At this point you should go into the 2D views and adjust the lights so they're evenly spaced around the map. We've just added a ton of lights to the map, and at the default brightness they'll totally wash out the scene. Control-select all the florescent lights, turn the brightness down to 6, then rebuild the lights and try the level.

Next we need to add sunlight streaming in through the hole in the ceiling. Place a light source roughly half-way up the tube and centered. Then set the brightness to 254. Rebuild the lighting. At this point, try placing the light higher and lower in the tube, rebuilding to see the effect. I wanted just the inside edge of the circular platform to be lit, so I left it halfway down the tube.

For such a prominent object in the map, the floating pyramid looks a little dull. We can fix that up by using the "special lit" technique. Special lit lets you pair lights with surfaces. In other words you can create a light that will only affect surfaces marked special lit. Right click any one of the pyramid's surfaces, then select all adjacents (shift-j). Open the surface properties and check "Special Lit". Rebuild the lights and you should see the pyramid go dark, since we haven't added any special lit light sources.

Add four light sources near the four sides of the pyramid. Control-select the four light sources and open the light properties window. Expand the Lighting menu and set bSpecialLit to True. Rebuild the lighting and the pyramid should now be lit by the four light sources. Notice now the light sources don't effect the rest of the scene, only the surfaces of the pyramid that we set to Special Lit.

Since special lights only effect surfaces set to special lit, we can afford to splurge a little on the lighting effects without bogging down the frame rate. In the Lighting menu set LightEffect to LE_SlowWave. Then expand the LightColor menu and set the brightness to 150, the hue to 60 and the saturation to 0. Rebuild the lighting and run the map. The pyramid should now have an eerie green glow.

The only thing wrong with this effect is that the greenish glow doesn't effect the surrounding environment. To add a LE_SlowWave light to the scene would put a bit of a strain on the 3D engine. So we'll just add a colored, static light source above the tip of the pyramid and set its properties to brightness 64, hue 60, and saturation 0.

Rebuild the map and we're done!

You can download the finished map here.

Future tutorials will cover more complex lighting effects like fog, spotlights, and a neat trick you can do using a flashlight beam and a mover.


Lode's All about Lighting Tutorial

Lode's All about Lighting Tutorial v1.45

By : Lode Vandevenne

lode@altern.org

Lode's Unreal

Table of Contents

  • Introduction
  • Adding a Light
  • Dynamic Light Modus
  • Moving a Light
  • Rebuild Geometry & Lighting
  • Colored Lights
  • ZoneLight
  • More ZoneLight Properties
  • LightRadius
  • Radii View
  • LightType
  • LightEffect
  • Changing the Direction of SpotLights
  • BlackLights
  • More Lighting Properties
  • Two Color Pulse, Two Color Strobe
  • Coronas
  • Animated Coronas
  • Sprites
  • Fog (Volumetric Lighting)
  • ZoneFog/Screen Flashes
  • Unlit
  • Special Lit
  • Bright corners
  • Shadow detail
  • TexturePaletteLoop
  • TexturePaletteOnce
  • Making any Object Give Light
  • Adding Sound to a Light
  • Lights in Actor Class Browser
  • TorchFlame
  • LightSources
  • LightBoxes
  • TriggerLights
  • Tubelights that Flicker On
  • Movers & Lighting
  • Fake Shadows
  • Moving Lights
  • Moving Coronas
  • Scale Lights
  • Light through Solids
  • Light through Non-Solids
  • Searchlight, Flashlight and Flare
  • Translucenty of a Surface
  • Coronas in a Skybox
  • Lightnings
  • ThunderLightning
  • Visible Lightnings
  • Is My Map Too Dark?
  • Lighting Tips
  • The Example Map
  • Download
  • What's New?
  • Contact

Introduction

There is just so much to tell about lights and they have so many properties, and I've never seen a tutorial that handles all of it, so I made one.

This is not a beginners nor an intermediate or advanced tutorial. This is a tutorial for everyone, even the most advanced mapper will learn something.

This tutorial is optimized for UEd2, but if you have UEd1, you can use this tutorial as well, because these two versions don't differ that much. And I've added remarks for UEd1 when there is a difference. You can of course apply the official UT 420 or higher patch to get UEd2. I recommend patch 436 or higher, because this one adds even more new features such as realtime preview of skyzones, editing the textures of a mover and a replace textures function.

If you want to print this tutorial: it's 71 pages here, but the number of pages might differ for you if your printer cuts pictures in half or not. You can use "multiple pages per sheet" to reduce the wasted paper and ink.

Adding a Light

First you need a room to add the lights, so create one that's big enough (you're going to add a lot of lights during this tutorial, so you'll need a lot of space)
Once you have a room, right click somewhere in the 3D view, and in the menu that appears choose Add Light Here. Now you see somewhere near the place you clicked, a small torch picture appear. That's a light source!

Right click on a wall, ceiling or floor...

...choose Add Light Here...

...and you get a lightsource.

Dynamic Light Modus

If you have the 3D view in Dynamic Lighting mode, you should also see that the walls around the light become brighter.
The 3D view has different modi, some of them are important when working with lights. To select one, use the buttons on top of the 3D view or search the menus of the 3Dview. The buttons that are green on the screens are the ones you must press to activate that mudus.

Textured: this will show all the walls of your map fullbright, and ignore all the lighting. This is not the way the walls will look in UT, in UT the lighting is always as in the Dynamic Light modus. There is an option NoLighting in UT, but that doesn't work when playing multiplayer, to prevent cheating. Only use this modus if you want to check the original texture of a wall that is too dark or colored by the lights.

Light modus: Textured

DynamicLight: this will show your map with all lightingeffects. If you rebuild lights and you haven't added any lights yet, you'll see only black. This modus shows the lighting like it will look in UT, so always use this one when working with the lighting of your map.

Light modus: DynamicLight

Realtime Preview: you can switch this on and of in all the views: click the button that looks like a little joystick on top of the view, or select a view and press p. Do not press the joystick on the main toolbar of the editor, that one starts UT to test the map. If a view is in realtimpreviewmode, it is always realtime updated, so if you change something in one view, you'll see that change also in the other view if it's in that modus. But this slows down the editor a bit. Another important thing about this modus, is that you can see animations like flikkering lights (see further in this tutorial) or animated textures. If Realtime Preview is off, you are not able to see how flikkering lights flikker.

The joystickbutton activated: Realtime Preview

For this tutorial, please set the 3D view in DynamicLight modus. Activate RealtimePreview when busy with LightEffects, LightTypes and other animations.

Moving a Light

When you placed the light, it probably isn't at the right place. To move it, first select it by clicking on it's torch symbol in any of the views. It should become green. Now select a 2D or a 3D view and use the following key combinations to move it:

  • To move it left, right, forwards or backwards in the 3D view, hold down CTRL and left or right mousebutton, and drag the mouse
  • To move it up and down in the 3D view, hold down CTRL and both mouse buttons together, and drag the mouse
  • To move it in a 2D view, hold CTRL and drag it with left mousebutton. You will move the object north, east, south, west, up or down depending on what 2D view you use
  • To zoom in or out a 2D view, hold down both mouse buttons and drag the mouse

If you use these mousebutton combinations without CTRL, you move around the camera, that is yourself.

Rebuild Geometry & Lighting

You cannot create a working map without rebuilding geometry, lights and eventually paths.
If you don't rebuild geometry you might get squished if you enter the map in UT. Every time you add a new polygon in the editor the geometry changes, so if you want to play or test your map after you made changes to this, rebuild geometry before saving. To rebuild geometry, you have to press this button in the upper toolbar of UEd2.

If you have a small map, this takes less than a second, but if you have a large map, rebuilding can take up to several minutes. After you rebuilt geometry, you see that all the walls become bright, as if there were no lights. This is because rebuilding geometry deletes all the info on lighting in your map. To get the light effects back, you have to rebuild lighting.

This calculates the light of each lightsource on each wall and object and casts shadows caused by walls or objects. To do this, press this button in the upper toolbar of UEd2.

There is also a Build Options button. If you press this one, a window appears. In there, press the build button, and everything that you selected (geometry, BSP, lighting & paths) will become rebuilt automaticly.

And in version 436, an extra button is added to rebuild everything at the same time automaticly.

Instead of using the buttons, you can also open the Build menu and select one of the choices.

If you are using UnrealEd1, go to Options and choose Rebuild. In the window that appears, press the Rebuild Geometry button to rebuild geometry, and then use the Lighting tab to rebuild lights.

Colored Lights

To make a colored light, select a light (a torch symbol), right click on it and in the menu that appears choose Light Properties, in the Light Properties window, expand LightColor and in there choose a color by changing one of the values.

The LightColor tab.

The LightColor in UEd is based on the HSB model: you'll see three values: LightBrightness, LightHue and LightSaturation.

  • Use LightBrightness to change to amound of light that the source will give: if you set it to it's max of 255, you'll have a very bright light, if you set it to zero, there won't be any light at all
  • Use LightHue to change the color of the light. To see the effect, LightSaturation must be low enough, so set it to around 64. A lightHue of 0 is red, 40 is yellow, 80 is green, 160 is blue, 200 is violet and 255 is red again
  • LightSaturation is used to change the intensity of the color. If it's at it's default value of 255, the light will be white and thus have no color. But if you lower it, it will have the color defined by LightHue. The lower, the more intense the color

there also is an easier way to change the color of the light, but this is only available in UnrealEd2. If you click on the LightColor expansionfield, you'll see a button Color. Press it and you'll see the Windows Color Dialog Box. Just select your favourite color and press Ok.

Window's Color Dialog Box

ZoneLight

Another way to create light in your maps is using zonelight. ZoneLight will enlight to a whole zone without having to add a lightsource. There are two kinds of zones: the ones without a ZoneInfo in it, and the ones with a ZoneInfo in it.

To add light to the ones without ZoneInfo, open the menu View and in there choose Level Properties. If you have UnrealEd1, it's in the menu Options, or you can press F6. You now see the Level Properties window. In there, expand ZoneLight

If you have zones in your map with ZoneInfos (such as a normal ZoneInfo, SkyZoneInfo or WaterZone), select the ZoneInfo, right click on it and choose ZoneInfo Properties and in there, expand ZoneLight.

If you don't know anything about Zones and ZoneInfo, you probably don't have any in your map. In that case, Level Properties will do. If you want to understand more about zones, water and skyboxes, read a tutorial about it, for example at http://www.planetunreal.com/unrealed.

The ZoneLight tab

To create the ZoneLight, enter a value in AmbientBrightness. The higher the value, the brighter the ZoneLight will be. It's default value of 0 means there is no ZoneLight. For example this is a map with all the lights removed, and AmbientBrightness set to 0, so it's completely black. On the second screenshot, AmbientBrightness in the properties of the ZoneInfo was set to 255, so the map is bright.

AmbientBrightness set to 0

AmbientBrightness set to 255

As you can see the it's very boring light, so never use ZoneLight without normal lights. In fact, never make the AmbientBrightness higher than around 32, it's much better to use nothing but normal lights, and use the ZoneLight only to reduce the shadows a bit.

To get colored ZoneLight, use AmbientHue and AmbientSaturation. The color of the ZoneLight is based on the same HSB model as the normal lights.

If you have a SkyBox, never forget to add light in the SkyZoneInfo (or with normal lights) or you'll have a black sky.

More ZoneLight Properties

There are some more settings in the ZoneLight properties of a ZoneInfo. They don't do anything about the lighting of a map, but some of them are useful.

  • TexUPanSPeed and TexVPanSpeed: This determinates the speed at which surfaces you have set to U-Pan or V-Pan will pan. For example if you have a skybox with panning clouds, enter a small value in TexUPanSpeed to make the clouds move slower, and enter a high value to make them move faster
  • EnvironmentMap: It's not known what this option does, it's probably old garbage from the pre-release version of the Unreal engine
  • FogColor and FogDistance: this might have been an attempt to create environment fog in the pre-release version of the Unreal engine. However it does not work.

LightRadius

Select a light (a torch symbol), and right click on it. In the menu that appears, choose Light Properties. In the Light Properties window, expand Lighting

The Lighting properties.

You should see the value LightRadius there. That value determinates how far the light will shine. When adding a corona to a light, it will also determinate till which distance the corona is visible.

Click on the LightRadius field and enter a number. Make sure the RealTimePreview of the 3D view is on so you can immediatly see the effect of the value you entered.
If you set it to 0, there will be no light, and the higher you set the number, the further the light will shine. If you think the max value of 255 isn't far enough, there are several things you can do:

  • Use ZoneLighting
  • Use LightEffect LE_Cylinder or LE_NonIncidence (see further in this tutorial for LightEffects)
  • Just use multiple lights

Radii View

There is a useful option in the editor that you can use to see the radius of the light in the 2Dviews: rightclick on top of one of the 2D views, in the menu that appears choose Actors, and there check Radii View. As long as this option is enabled, you'll see a red circle appear around the light(s) you have selected. You only see it if you have selected the light: to select one leftclick on the torch symbol. These red circles are usually very large (the one on the screenshot below is for a Light Radius of 13). Because the lights shine the further the less bright, the red circle seems larger than the lightradius looks in real. Sometimes the circle is so large that it doesn't appear. That means that it is bigger than the 2D view. You have to zoom out to see it.

The red circle shows the radius of the light

LightType

The LightType determines if you light will be always on, always off or an animated combination of bright and dark by flickering, pulsing, blinking and so on. It can even loop through different colors if you use TexturePaletteLoop (this is explained in the section TexturePaletteLoop of this tutorial). Go to the Light Properties (right click on the light and select Light Properties in the menu that appears), expand Lighting and click on LightType. You should now see all the LightTypes.

The list of all LightTypes

I'll give a detailed description of each LightType, but first make sure the 3D View is on RealTimePreview

  • LT_None: If you select this, the source will not give any light. The light is Off.
  • LT_Steady: This is the default and makes the lightsource giving light.
  • LT_Pulse: Makes the light pulse. It will become brighter and darker then again brighter and so on. It will not just switch between On, Off, On, Off,... but fade from On to Off to On to Off....
  • LT_Blink: The light will randomly go On and Off. It will be most of the times On. For some reason, UEd2 seams to have a problem with this LightType. It might happen that when you select this, the light will be just steady. Play a little bit with the LightPeriod slider to solve this. This problem does not occur in UT.
  • LT_Flicker: the light will go randomly On and Off. In contradiction to LT_Blink, it will be most of the times Off. This is very handy to make a broken tubelight, certainly if you add a sound to it that flickers together with the light (see further in this tutorial.)
  • LT_Strobe: The light will switch between On, Off, On, Off,.... In contradiction to LT_Flicker and LT_Blink, this does not happen randomly. In contradiction to LT_Pulse, it will not fade from On to Off to On to Off....
    -LT_BackdropLight: Nothing special about this one. The light is just steady. This is probably an old remainder of the pre-release version of Unreal.
  • LT_SubtlePulse: Like LT_Pulse, but less heavy.
  • LT_TexturePaletteLoop and LT_TexturePaletteOnce: I'll handle these further in this tutorial.

LightEffect

LightEffects are animations of the light that not only change the brightness of it, but also the direction and the shape of the shine on the walls. But if you use too many LightEffects, this could really slow down the processor, so to keep a good performance in your maps, don't overdo this.

Go to the LightProperties and expand Lighting. There click on LightEffect. You get a list of all the LightEffects.

The list of all light effects.

I'll give a detailed description of each LightEffect and give screenshots of each one, but first make sure the 3Dview is on RealTimePreview.

LE_None: This just a normal light. In contradiction to LT_None, LE_None does not mean that the light is Off.

LE_TorchWaver: Makes the light move like a torch.

LE_FireWaver: This does the same as LE_TorchWaver, but heavyer. The light will move like fire. Handy to use when you create a fire or a torch. (On the screenshot below, it isn't good to see, because in reality it moves)

LE_WateryShimmer: The lighting will move like water. Use it when you create a pool inside a building, to shine on the walls of the building. Or use it underwater in any pool.

LE_Searchlight: The lightbeam will rotate, like a searchlight. Think about Alcatraz. If LightPeriod is 0, the SearchLight will not rotate.

LE_SlowWave: Some kind of animated wave-effect.

LE_FastWave: Same as LE_SlowWave, but faster.

LE_CloudCast: Looks to be just steady. This is probably an old remainder of the pre-release version of Unreal.

LE_StaticSpot: The light will beam in one direction. Look further in this tutorial how to change the direction and the size of the beam.

LE_Shock: Another animation for the light.

LE_Disco: A nice disco-effect.

LE_Warp: Looks to be just steady. This is probably an old remainder of the pre-release version of Unreal.

LE_SpotLight: The same as LE_StaticSpot. Look further in this tutorial how to change the direction and the size of the beam.

LE_NonIncidence: like LE_None, but the light will have almost no fading-away at the edges. This makes it look like the radius is larger. Compare this screenshot to the one of LE_None. The LightRadius is the same for both lights.

LE_Shell: If you use this correct (close enough to wall), the light will look like a ring on the wall. In larger rooms, it might look like the blue screenshot.

LE_OmniBumpMap: Can be used to create blacklights (see further). This is not what the name suggests, so this is probably an old remainder of the pre-release version of Unreal.

LE_Interference: Another animation for the light.

LE_Cylinder: I use this if I need a really large LightRadius. The lightradius is calculated as a cylinder instead of a sphere with soft edges.

LE_Rotor: The light looks as on the screenshot, and rotates.

LE_Unused: Exactly the same as LE_None. This is probably an old remainder of the pre-release version of Unreal.

Changing the direction of SpotLights

To change the direction of the beam of a SpotLight or a StaticSpot, use the Rotation Tool

If you have Unrealed1, use this button:

Now, select the light. Hold down CTRL and the right mousebutton to rotate it from left and right, and use left mouse button to rotate it up and down.

You can make the spotlight to have an arrow in the 2D views. To do this open Advanced in it's properties and set bDirectional to True. The arrow indicates the direction of the light. This has no effect on the look of the map in UT.

BlackLights

You can make lights that don't illuminate the textures, but only actors and objects. This way, they approach the blacklights used in dancings. If you make a dark room, with no normal lights in it, only a BlackLight, and then play the map, you will see nothing, only your opponent, the weapon you are holding in your hand and objects such as trees, crates and tables that you placed in there.

To make a BlackLight, add a light and set it's LightEffect to LE_OmniBumpMap. That's it! What you created now is not really spectacular. To make the BlackLight more spectacular, you can give it another color and LightEffect, for example set LightType to LT_Strobe, and make it violet.

You can use this effect to make a dancing, but you can also use it in a more subtle way: in a normally illuminated room, you can add a few of these blacklights to make players and objects brighter than the rest of the room. Or you can use it for special maps in which you can only see opponents and no walls.

The actors are illuminated by the blacklight, but the walls are not.

More Lighting Properties

Again, open Light Properties of the light and expand Lighting. Notice the following properties: bActorShadows, LightCone, LightPeriod & LightPhase.

bActorShadows: This was supposed to let the light cast realistic shadows of actors, but it doesn't work.

bLensFlare: This doesn't do anything. This is probably an old remainder of the pre-release version of Unreal. You could enter about 15 different coronatextures and make the effect of LensFlares in a camera. However, this is left away in the final version of Unreal.

LightCone: If the LightEffect is SpotLight or StaticSpot, use this to change size of the lightbeam.

LightPeriod: Use this to change the speed of the light-animations LT_Pulse, LT_SubtlePulse and LE_Searchlight. This does not work for the LightEffects and LightTypes, not even the LT_Strobe. The lower the number, the faster the animation will run. For LE_SearchLight, it moves at it's fastest when LightPeriod is 1. When it's 0, LE_SearchLight will not move at all.

LightPhase: use this to set the phase of the animation-cycle the light will start with. For examle: if you have 2 Pulsing (LT_Pulse) lights, and want the first one to fade in while the second one fades out you'll have to use this slider. Add two lights close to a wall. Set the lighttype of both of them to LT_Pulse. Now select one of them and set it's LightPhase to 128. An animation-cycle takes 255 steps, so 128 is exactly the middle of the animation. This means that while light one is in the start of the animation (= fading out), the second one is already in the middle of the animation (= fading in).

Two Colored Pulse, Two Colored Strobe

If you want for example a pulsing light that does not becomes red, black, red, black but red, green, red, green, you have to use the trick explained in this section.

To make a pulsing light that fades from red to green, first add two lights. Do not yet place them on the same place, otherwise they're standing in each others way so it's difficult to select each one of them. Select the first light and open it's Light Properties, and set it's LightType to LT_Pulse. Now expand LightColor and set it's color to green (use a low saturation). After you've done this, select the second light and set it's LightType to LT_Pulse. Set it's color to red (again a low saturation). Make sure both lights have the same LightPeriod. Set the LightPhase of one of the lights to 128, and the other light's to 0. Now place both lights on exactly on the same place, so it will look like it's one light that does a TwoColorPulse.

To make a TwoColorStrobe, do the same but with LT_Probe.

Another way to make this kind of effects, is using TexturePaletteLoop. You can read more about this further in the tutorial.

Coronas

A corona is a 2D picture placed on the lightsource. It is not like a 2D sprite, because 2D sprites become smaller on your screen if you walk further away from them. The corona of a light is alway as large on your screen.

To give the light a corona, open it's Light Properties and expand Lighting. In there set bCorona to True. Now, open the Texture Browser. To do this, open the menu View and there choose Texture Browser. If you have UEd1, the Texture Browser should be open already, if not, just search in all the menus or read a beginners tutorial about UEd1. Also, in version 436 of UEd2, they have forgotten to add the Texture Browser in the menu, but you can use the button in the upper toolbar that looks like this:

In the TextureBrowser, open the menu File and there choose Open. In UEd1, just click on the Open button. Go to the Textures folder in your Unreal Tournament or Unreal folder, and open GenFX.utx. The package GenFX has multiple groups in it, one of them is called LensFlar. See screenshot below to see which dropdownmenu to use to open LensFlar: I painted a red circle around it. If you have UEd1, probably all folders will be visible, so ignore this. Now you should see a lot of lensflare pictures. Choose one and select it.

The LensFlares of GenFX

GenFX is the main package for coronas, palettes, etc..., but there are more corona textures in other packages and groups. For example City.utx has some.

Now go back to the Light Properties and expand Display.

The Display tab

Click on Skin. A button Use appears. Click that button and the name of the texture you selected should appear in the textfield. Before you can see the corona in UEd, you have to rebuild geometry. After that, also rebuild lighting. Now you'll see the corona in the 3D view. If you don't see it, make sure the camera is close enough to the light if it has a small LightRadius and that the camera is not inside a wall. If you still don't see it, it might be that your software or hardware modus doesn't has the corona option enabled. go to the Fog-section of this tutorial and read the first part of it, but instead of tutning on the VolumetricLighting option, turn on the Corona option.

If you think the corona is too small or too large (it will probably be too large), use Display in the Display expansion of the Light Properties. Try entering different values in it. 0.2 is most of the times perfect.

The LightRadius value does not only determine how far the light will shine, but also from which distance you start to be able to see the corona.

If you want to make a light with a very small radius but a corona that's visible from very far, just use two lights: one without corona that gives light in small radius, and one with corona, LightBrightness set to 0 and a large LightRadius. Then place these two lights on the exact same position.

Coronas in DOM-MetalDream

Animated Coronas

To make an animated corona, use an animated texture as skin. But there is a problem: there are no animated corona textures avaible in the standard texture packages. You have to make one yourself.

To make a strobing corona, select a standard coronatexture and look at it's size (it's size should appear on top of the Texture Browser window). Most of the times they are 128*128 or 64*64. With any painting program, make a completely black picture that has the same size as the corona. Save it as a 256 color PCX-file. Now go back to the texturebrowser, and select the coronapicture. open the menu File of the texturebrowser and choose Export. In UEd1, just click on the Export button. Save the flare as a PCX-File. After that, click Import. Open that same PCX-File you just saved, and in the Import Texture window, type the following things:

The Import Texture window

Make sure that you type a packagename that DOES NOT already exist, or you'll overwrite an existing package and destroy your UT!

Press OK. Now again choose Import, but this time open the black texture you created. In the Import Texture window, type the same Package as before. Use a different Name for the texture. (for example StrobingLensFlarePart2)

After you did this, select the package you created and in there you should see the two textures: The lensflare and the black one. Select the LensFlare texture and in the menu Edit of the Texture Browser, choose Properties. Or rightclick on the lensflaretexture and choose properties. In UEd1 select the texture and press the Edit button on the bottom of the Texture Browser. In the Texture Properties window that appears, expand Animation. Go back to the Texture Browser and select the black texture. Now go back to the Texture Properties, click on AnimNext and click the Use button. The name of the black texture appears. You'll also see that the example will strobe. Change the MaxFrameRate value to change the strobing speed. The higher the value, the faster it strobes. Setting it higher than 16 doesn't appear to work. The lower the value, the slower it strobes.

The Texture Properties window, and the Texture Browser.

Before you can use this in your maps, you'll have to save your ChooseAName Package. Open the menu File of your TextureBrowser and choose save make sure you DO NOT overwrite an existing package, or you'll ruin your Unreal Tournament. Save it as the same name you already gave it, in my example ChooseAName.utx. If you called the package MyLevel you don't have to save it, it will be saved automaticly in the *.utx file of your map then. However, this also means you can't use the package for other maps.

Now select any light and give it your strobing texture as skin. The animation will only be visible in Unreal Tournament, not in the editor.

Why using this? Because the coronas in the Unreal engine have a big problem: when you set the LightType to LT_Strobe, LT_Pulse, LT_Flicker or whatever, the light will strobe but the corona will not, which is not very realistic. But the animated corona you just created strobes. Of course, your timing needs to be perfect...

To make a rotating corona, export the standard corona texture you want and open it in any painting program. In there, rotate the corona a little bit and save texture as a new PCX-file, rotate again, save again, etc... untill you're rotated back to the original position. Rotate at for example 30 degrees to have 12 different animation frames. Import the textures in a new texture package. In the Texture Propoties, first select the first texture and set it's AnimNext to the second one, set the AnimNext of the second one to the third one, ... , and set the AnimNext of the last one back to the first one. Play with the MaxFrameRate and MinFrameRate to try out different effects. And of course save your texture package and make sure you don't overwrite an existing one!

You can also create coronas that change color, grow and shrink, or anything else.

Sprites

In old 3D games, such as Wolfenstein 3D, Doom and Duke Nukem 3D, the objects were 2D pictures. No matter from which angle you looked at them, they always looked the same. The soldiers in Wolfenstein had 8 pictures, so you could see them from 8 different angles, but that still isn't 3D. What does this have to do with lighting? You can use the lights to create the effect of sprites in Unreal. You can also do this with other object, but lights are one of the few that don't have a mesh, so they are easier to use for this purpose. How? Make a light and set its LightBrightness or LightRadius to 0 (you don't have to do that, if you want the object to give light). Open it's LightProperties, and expand Advanced. In there, set bHidden to False. This means that the torch symbol will now also be visible in Unreal Tournament, and not in the editor only. The only thing you've got to do now is to change the torch picture in another picture. Open the texturebrowser and select anything you like. If you import a picture, make sure that you set it to be masked if you don't want a black square around it. Masked will make the first color in the palette to become transparent, in most cases this is the black. Go back to the Light Properties and expand Display. Play with the following settings:

  • Drawtype: this determinates what kind of object you have. DT_Sprite creates 2D objects, DT_Mesh (see further) creates 3D objects.
  • To change size of the 2D object, use DrawScale.
  • To change the lightness or darkness of it, use ScaleGlow. In most cases you have to use this, because the sprites ignore lighting and this is the only way to let them be dark in a dark room or bright in a bright room. If the style is translucent, ScaleGlow doesn't change the brightness, but it's translucenty.
  • Use Style to make it translucent, modulated or masked.
  • To make the objects not walkthroughable, Expand Collision and set BlockActors, BlockPlayers, CollideActors and CollidePlayers to True and choose a height and Radius.

The Collision tab

You can of course also use this 2D-objects effect for other things, for example if you use the texture of an eyeball, the eye will always look in your direction.

Some 2D Wolfenstein Sprites

Fog (Volumetric Lighting)

Fog isn't called fog in the Unreal Engine, but Volumetric Lighting. Creating fog is quite difficult, and it also slows down the computer. Fog in Unreal isn't like fog in for example Delta Force II, and making a foggy outdoor map is almost impossible. Most Unreal Tournament players don't even have the Volumetric Lighting propertie set to True, so they won't be able to see the fog. Probably even you don't have it enabled. To enable it, or to check if it is enabled, you must open the Advanced Options Window. This window is somewhat hidden, but there are several ways to open it:

  • By entering a command in the console. To enter a consolecommand in Unreal (Tournament), press the Tab key in a game or use the Tools menu in the menu. The console of UnrealEd2 425 or higher is the Commandfield on the bottom.
  • By choosing it in a menu. In Unreal 1, go to Options and there choose Advanced Options. Or in UnrealEd2 open the menu View and there choose Advanced Options. Unreal Tournament does not have a link to it in it's menus.
  • You can also edit the UnrealTournament.ini instead of using Advanced Options. Search for the VolumetricLighting setting of the correct 3D modus, and set it to True.

In the Advanced Options window, expand Rendering and in there expand Software rendering. That's the modus that UnrealEd uses in most cases. If it uses Direct3D, expand that one. In there, set VolumetricLighting to True. If your map already has fog, you can see it in your editor now. Notice that there are lots of other options. Make sure Coronas and ShinySurfaces are set to True and that FastTranslucenty is False because that's ugly and is only for very slow computers. ShinySurfaces are mirrors.

The Software rendering properties

To be able see fog in Unreal or Unreal Tournament, expand the 3D modus that your Unreal Tournament uses, in this example Direct3D, and there set VolumetricLighting to True.

Direct3D properties

To create fog you need a lightsource, placed in a FogZone.

If you want to place the light in a zone without ZoneInfo, go to Level Properties. If you don't know how, read the section ZoneLight of this tutorial. In the Level Properties Window, expand ZoneInfo and in there set bFogZone to True. If you want the fog in another zone, right click on the ZoneInfo actor and there xpand ZoneInfo and in there set bFogZone to True. Now select the light that will become fog, and open it's Light Properties. Expand Lighting. There are three values important for Volumetric Lighting.

  • VolumeBrightness changes the brightness of the fog.
  • VolumeFog changes how thick the fog is: the higer this value, the less far you can see in the fog.
  • VolumeRadius: this changes how far away from the light the fog will reach. If set to 0, there will be no fog.
  • To change the color of the fog, change the color of the light, in the LightColor expansion.
  • You can use any Lighttypes and other properties as well.

A room with green fog

You can also use fog to create coronas: just give it a really small radius.

A corona created with Volumertic Lighting

ZoneFog/Screen Flashes

As you can have ZoneLight, you can also have ZoneFog. You can create this effect by using Screen Flashes. To enable it, open the ZoneInfo or LevelInfo properties and expand ZoneLight.

The ZoneLight tab

Expand ViewFog, and you'll see 3 values: X, Y and Z. X stands for Red, Y stands for Green and Z stands for Blue. Enter values between 0 and 1 in it. ViewFog creates a translucent layer of the RGBcolor you entered on your screen, so it appears like fog. For example if you enter X=1, Y=0 and Z=0, you'll have really red fog in that zone. To get white or grey fog, give X, Y and Z the same value, for example 0.5, 0.5, 0.5

ViewFlash needs values between 0 and -1. It reduces the ViewFog a bit.

You can't see this fog in the editor, and you can only see it in UT if you have the screenflashes option enabled. Go to the Advanced Options of UT (see the Fog section for that) and expand Display. There set ScreenFlashes to True. These Screen Flashes are also used to turn the screen red when you're hit by someone, and for example WaterZones have green ZoneFog.

No ZoneFog

Blue ZoneFog

Unlit

When you place any light or use ZoneLighting, the walls are affected by these lightsources. But it is possible to make the walls ignore the lighting and just be completely bright, even if they are in a dark room. Create a normal cuberoom, add some very dark lights in it and make sure ZoneLighting is set to 0. Now rebuild lighting. You'll see nothing but black now. Now select one of the walls. Blue dots should appear on it. Right click on it. In the menu that appears, choose Surface Properties. (In UEd1 doubleclick on the surface does the same). In the Surface Properties open the Flags-tab.

The Surface Properties window

There activate Unlit and rebuild lighting. Notice how all the walls of the room are dark, exept the one you set to Unlit. Just for fun, add a light in the room. The dark walls will be affected by the light, but the unlit will remain unaffected. They also ignore ZoneLighting.

None of the walls are unlit

A unlit wall

Use this option for example for surfaces that are giving light, such as lava or computer screens. Also add some lights around it to make the other walls appear to be enlighted by the lava or the screen.

The surface propertie Force View Zone does the same as unlit.

To make objects unlit, open Display in their properties and set bUnlit to True. Now, the brightness of the object depends on it's scaleglow setting only.

Special Lit

Again make a normal cuberoom, and add two lights in it: a red one and a green one. Give them a high LightBrightness and LightRadius, and a low LightSaturation. Rebuild geometry and lighting.

No Special Lit

Select one of the walls and open it's Surface Properties, and activate Special Lit (make sure Unlit is Off). Rebuild again. The Special Lit wall is just black, while the others are still illuminated. That's because walls that are set to Special Lit, don't get light from the lights you added. Note: Special Lit walls DO get light from the ZoneLight, so if it doesn't look black check if there is ZoneLight.

The special lit wall is black

They can only be enlighted by lights that are set to special lit as well, or by ZoneLight. Open the Light Properties of the red light and expand Lighting. Now set Special Lit to True and rebuild lighting. The normal walls are green and the Special Lit wall is red.

The Special Lit wall gets red light from the Special Lit light

You can use the Special Lit option for two things: to make black walls (if you don't add any Special Lit lights, and there is no ZoneLight), and to make lights that may shine on one thing but not on another. For example if you want to make a computer screen that pulses if you don't want the environment to flicker, you'll have to add a light in front of that screen and set the LightType to LT_Pulse and set the screen surface and the light to Special Lit.

Bright Corners

There is another surface property, called Bright corners. If this is not activated, the corners of the walls will be darker than the center of it. If you activate it, the sides of the wall will be as bright as the center. Use this for outside landscapes or if you don't want darker corners in a room. You can see the difference on these screenshots:

Dark corners

Bright corners

The size of the corners is determinated by the scaling of the texture you used (to scale the texture of a surface, use Scaling in the Alignment tab of the Surface Properties). If you use a really large scaling for a texture, it's corners will be so big that the whole surface will be black no matter how many lights you place next to it. In a 256*256*256 room with a normal light in it, a texture with a scaling value of 4 will be hardly illuminated! Also, if you have really small surfaces with a scaling of 1, the corners will still be larger than the surface. Of course, if you set Bright corners to True this problem will not occur.

An example of such a problem, that really annoyed me, is when you subtract a tubelight in the ceiling. As long as it has dark corners, the whole tubelight will be black. Only after you enabled Bright corners for these surfaces you will be able to see them.

Dark corners (too dark)

Bright corners

Shadow Detail

The quality of the lightmaps on a surface depends on the Shadow detail you give it. Open the Surface Properties of the walls, floor and ceiling of a room and try these things. Always rebuild lighting after altering a propertie, to see the result:

  • High Shadow Detail: The lighting on the wall will have a higher quality. Use this if you want for example the light through a window, fence, ... casted on the floor realisticly, as you can see on the screenshot.
  • Low Shadow Detail: Lower quality, higher performance.
  • If you check High ánd Low Shadow Detail, the wall will be Ultra Low Shadow Detail

Set the surfaces to high shadow detail to get realistic light effects

TexturePaletteLoop

This is a cool feature of the Unreal engine, that not many people know: you can make the lights loop through different colors. To do this, open a light's Light Properties and set it's LightType to LT_TexturePaletteLoop. Now go to the texture browser and open the package GenFX.utx or Palettes.utx. In these packages are good palettetextures.

The gradients of GenFX

The palettes

Select one of the palettetextures, and then in the Light Properties, expand Display and click on Skin (the same thing you use to create a corona). Press the Use button.

Use a gradient or palette as Skin for the light

The light will loop only through the colors of the palette (in their order) from the texture you used. It ignores the texture itself. If you want to make a light that fades from red to green to blue to yellow back to red etc... and don't find a texture for this, you'll have to use a program like Paint Shop Pro or PhotoShop and make a new 256 color texture. To edit the palette in PSP7, open the menu Colors and there choose Edit Palette.... However, editing the palette is a long and boring job. There exist specialized programs to do this, but I don't know any names at this moment.

Now set the 3D view to RealTimePreview and DynamicLight modus and view the light changing color. If it isn't clear enough, try some other textures. To change the speed of the effect, use LightPeriod under Lighting. You can also use LightPhase and other settings to get the light exactly how you want it. However, the LightHue and LightSaturation settings are ignored.

You can use TexturePaletteLoop for example to create a fire: use a palettetexture with yellow, orange and red colors in it.

If you set bCorona to True, the palettetexture will also be used as coronatexture, because the same skin is used for corona and palette. This is ugly of course. If you want the TexturePaletteLight to have a corona, add a second light and set it's Brightnes to 0 (not it's LightRadius), give it a corona and place it on the same place as the TexturealetteLight.

If you have a discolight, with LE_Disco, it is very cool to combine it with LT_TexturePaletteLoop. As skin, use Candy from the Palette.utx package, because that is a real colorful one.

TexturePaletteOnce

TexturePaletteOnce makes the light go through the palette only once. It's used for the weapons, explosions, teleporters, spawnpoints, etc...: these cast a colored lighting effect that stays there only for a short time.

To get TexturePaletteOnce to work, there are three obstacles that you need to overcome:

  • It must have a Skin (the same way as TexturePaletteLoop needs a skin) and LightType set to LT_TexturePaletteOnce
  • You have to set 3 different Advanced Settings: LifeSpan, bStatic = False and bNoDelete = False.
  • It must be spawned during gameplay

The last obstacle means you don't have to place your light in the level, but instead you need to place something that spawns the light. You can use a ThingFactory + SpawnPoint, but here I'll use a very simple spawnscript instead. Then you need to make a new Actor Class: that will be the light that has to be spawned: in this new Actor Class you have to set the Default Properties (it's in there that you have to set LightType to LT_TexturePaletteOnce etc...), because it's impossible to tell a ThingFactory or the spawnscript I use here to spawn an existing actor with modified (= non-default) properties. However, when it spawns the new class you make, the default properties of this class will be used and that is exactly what you want.

Let's start with the spawnscript. If you want to use the ThingFactory instead, go to here. The reason I use this Spawnscript is because it's so much more simple than the ThingFactory: all it does is spawning the actor you want at it's location, every time when it's triggered. The other reason is because the lights with TexturePaletteOnce were only called by scripts anyway (for example by the explosioneffects etc...). In the Actor Class Browser select KeyPoint, then open the menu "Class" --> New..., and in the window that appears make sure after the word "Parent" the word "KeyPoint" appears (if it doesn't, press cancel and select KeyPoint in the Actor Class Browser before making the new class. Of course, if you want it to expand another class, just select that class instead, but then your script will differ a bit from the one I enter below). Type as Package "MyLevel" (because it's ridicilous to bother the players of your map to put a new *.u file in theis system folder for such a small script), and type as Name "SpawnThing". Now in the Actor Class Browser, double click on the newly created SpawnThing, and the script window should appear. Simple enter the following script in it:

//=============================================================================
// SpawnThing.
//=============================================================================
class SpawnThing expands KeyPoint;

var() class<actor> SpawnedActor;

function trigger(actor Other, pawn EventInstigator)
{
Spawn(SpawnedActor);
}

Then in the script window open the menu Tools and press Compile Changed (do NOT
press Compile All, unless you want to wait for a year).

Ok, now you have the SpawnThing, or you have a ThingFactory, now you need to make the new light class. In the Actor Class Browser select Light, then open the menu "Class" --> New..., and in the window that appears make sure after the word "Parent" the word "Light" appears. Type as Package "MyLevel", and type as Name "TPOnceLight" (or whatever other name you like to give it) and press Ok. Now select this newly created class in the Actor Class Browser, right click on it and open the Default Properties of the TPOnceLight (so DO NOT add this TPOnceLight in the level, just open it's Default Properties. In the Default Properties expand Advanced, set bNoDelete to False and bStatic to False. Then enter a LifeSpan: this is the time the light will live after it's spawned, and also the time it takes to loop through the palette. Once the light has gone through the palette ONE time, it's LifeSpan is finished and it disappears. Never leave LifeSpan at 0, or the light will die immidiatly (= useless!). For example if you enter 0.5, the light will finish the palette in 0.5 seconds.

After this, give it a Skin, as you did in the previous section: the palette of this skin determinates the colors the light will go through. Finally, set the LightType to LT_TexturePaletteOnce.

Now, the only thing that you have left to do is make the TPOnceLight get spawned when you want. First, select the SpawnThing you made in the Actor Class Browser, and add it in the level at the location where you want the TPOnceLight to get spawned. Then select the TPOnceLight in the Actor Class Browser, and open the properties of the SpawnThing in the level (NOT the default properties). In there expand SpawnThing, click on SpawnedActor and press the Use button. In the textfield, the name Class'MyLevel.TPOnceLight' should appear. Then in the properties of the SpawnThing --> Events --> Tag enter "TPOnceLightHere" (or any other Tag you want to give it).

Finally, you need a trigger or any other event to activate the SpawnThing. So add a trigger somewhere in your map, and in it's properties --> Events --> Event enter "Once" (this is the tag you gave the SpawnThing). You can of course also use any other event instead of the trigger, for example an event caused by a mover or whatever.

If you now walk in that trigger, it activates the SpawnThing. This SpawnThing then spawns the TPOnceLight at it's location. The TPOnceLight does his thing and then dies. Every time you activate the trigger again, a new TPOnceLight gets spawned, but of course all these new TPOnceLights will die after their LifeSpan so you don't have to fear an overload.

Go to the section Tubelights that Flicker On for something useful you can do with TexturePaletteOnce.

Making Any Object to Give Light

You don't need such a torch symbol to have lightsources in your map. Any object can be made to give light. For example chairs, trees, books, ... Open it's properties and you'll see that all the objects have a Lighting and a LightColor expansion. Sometimes you'll have to change a lot of properties before the object gives light, for example because it's lighttype is set to LT_None or it's LightColor or LightRadius are set to 0. There is however a minor problem with this: if you add for example a light to a shieltbelt, and someone takes the shieltbelt away, the light will still be there.

You can really set any object to give light, even brushes! However, if you set a brush to give light, this will only be visible in the editor, in UT the brushes are removed so also their lighting is deleted.

Adding Sound to a Light

You can also add an AmbientSound to a light. The cool thing about it is that if you use a LightType such as LT_Strobe, LT_Pulse, LT_Flicker, ..., the sound will Strobe, Pulse, Flicker, ... as well. Very useful for a broken tubelight! First open the Sound Browser (in menu View, for UEd1 it's in the same window as where the Texture, Class and Musidbrowser are). Open the soundpackage Extro.uax and select Light6.

The Sound Browser

In the Light Properties expand Sound. Click on AmbientSound and press the Usebutton. In the 3D view set RealTimePreview on and listen to the sound. Now set the LightType to LT_Pulse, and you'll here the sound fade away and fade back in, together with the light. Now set LightType to LT_Flicker, and hear the sound flickering as well.

You can also change Pitch, Volume and Radius of the sound, by using SoundPitch, SoundRadius and SoundVolume.

Lights in Actor Class Browser

In the actor class browser, you can find more lights than just the standard one you used until now. Open the Actor Class Browser (it's in the View menu of UEd2) and expand Light.

The Actor Class Browser with a list of all lightclasses

Most of these lights are just normal lights with some activated properties, like LightType or LightColor.

  • Light: this is the standard light that you used until now.
  • ChargeLight: If you look in it's ChargeLight Properties, you'll see that it has a LichtBrightness of 3 and a LightRadius of 3. And it's color is orange. Because of it's small brightness and radius, it's almost impossible to see the light.
  • DistanceLightning: In the editor, it just flickers, but in the game it will flicker only every 30 seconds or so, so this is very usefull for lightnigs and special weather effects. I'll handle this further in the tutorial.
  • FlashLightBeam: A yellow lightbeam, this light is used by the FlashLight in the game.
  • OverHeatLight: Doesn't give any light at all.
  • QueenTeleportLight: It's red and pulses, however it doesn't in UT because it has a LifeSpan and requires to be spawned during gameplay.
  • SightLight: It's green and has a small radius, but doesn't work in the game.
  • SpotLight: A spotlight, doesn't work in the game.
  • TorchFlame: see the section TorchFlame for this
  • TriggerLight: see the section TriggerLight for this
  • TriggerLight: see the section TriggerLight for this
  • TriggerLightRad: This doesn't work. If you right click on it and choose Edit Script, you'll see the comment "Broken.", as well as "Hi Andrew!".
  • WeaponLight: This is spawned by some weapons, and has got LT_TexturePaletteOnce.
  • EffectLight: same as weaponlight, but uses a blue texture.
  • PurpleLight: again the same, but (believe it or not) purple.

Only DistanceLightning, TorchFlame and TriggerLight are useful. The others are broken, or only work if they are spawned during gameplay.

TorchFlame

See in the section above and select the TorchFlame. Place one in a room.

A TorchFlame

It's a nice flame that gives light as well. There are a lot of properties that you can change for this flame: open it's TorchFlame Properties and expand Display.

  • Use DrawScale to change the size of the flame
  • Use Fatness to change it's fatness.
  • Use ScaleGlow to change it's translucenty.
  • Use DrawType to change how the light is drawn: now, it is DT_Mesh because the flametexture is a mesh. Normal lights use DT_Sprite for their 2D torch symbol.
  • Use Mesh to change the mesh: open Mesh Browser or click on the 3 dots next to the Use Button and you'll see the mesh browser. However there's only one flame mesh. In the mesh browser's 3D view, use left mousebutton to zoom and right mousebutton to rotate. Press the play button to play the movements of for example this nice Titan. Choose any mesh you want and press the Usebutton. But there is only one torch mesh, so except if you make a torch mesh yourself, this is not really useful.

The Mesh Browser

LightSources

To make your map realistic, it's best that you always make lightsources for the lights. I mean, if you place a light in a building, place for example tubelights in it. You can creating lightsources yourself by using brushes. But there are also lots of nice lightsources in the Actor Class Browser. Under Decoration: Candle, Candle2, Lamp1, Lamp4, Lantern, Lantern2, InterpolatingObject and under Decoration --> ut_Decoration (an expansion of Decoration): TubeLight and TubeLight2

In their properties, you can change their size etc..., look in the section LightBoxes of this tutorial for this.

Some of the LightSource Decorations

LightBoxes

You can give the lightsources a lightbox.

LightBoxes in CTF-Coret

The lightboxes are also an actor class. In the actor class browser, there is one under Decoration: LightCone, and there is one under Decoration --> ut_Decoration: LightBox

Open the LightBox Properties, and go to Display

  • Use DrawScale and Fatness to change the size of the lightboxes.
  • Use Style to make it normal, masked, translucent or modulated. Translucent is (of course) the standard setting. Modulated looks cool, but not useful.
  • Use ScaleGlow to change it's translucenty.
  • You can of course choose another mesh by using Mesh.

TriggerLights

For this section I assume that you know something about triggers, if you don't please read a tutorial about it.

To make a triggerlight that will toggle between on and off each time you touch the trigger, do the following: In the Actor Browser, expand Triggers and there select Trigger. Place it in your map on the place you want to be the switch of the light. Now, expand Lights in the actor class browser and there select TriggerLight. (There might be two TriggerLights in the list, but they are the same). Now place it in your map.

Open the Trigger Properties ot the trigger and expand Events and type a name in Event, For example NiceLittleLight. Now open the TriggerLight Properties and there exand Events as well, and under Tag type the name you typed in the Event of the trigger, in my example NiceLittleLight. In triggerlight properties expand Object and set InitialState to TriggerToggle.

Trigger Properties

TriggerLight Properties

You now have a working TriggerLight. You can use these properties, in the TriggerLight Properties:

  • bInitiallyOn: If true, the light is on when you start the map. For example if you have a TriggerToggle-light, it will be first on, and when you hit the trigger: off, etc..., but when this is false, it will be first off, then on etc...
  • ChangeTime: how long it takes to switch the light from one status to another. If the light is off, and you hit a trigger that turns it on, the light will fade from off to on in x seconds where x is the ChangeTime value. If it's at it's default value of zero, the light will not fade but will go immediatly on.
  • RemainOnTime: I have never seen this working.
  • bDelayFullOn: if this is true, and you have a changetime larger than zero, the light will not fade but wait for x seconds and then go on or off.

In Object you can change the InitialState of the light:

  • TriggerToggle: each time you hit the trigger, the light toggles between on and off. This is the one used in the above example.
  • TriggerTurnsOn/Off: Light will stay On/Off forever after touching the trigger. If you use TriggerTurnsOff don't forget to set bInitiallyOn to TRUE, otherwise you'll have a light that's always off.
  • TriggerControl: As long as you're inside the trigger's radius, the light is on, when you're outside of it, the light is off.
  • TriggerPound: This doesn't do anything useful for a light. TriggerPound is used for movers, but appearantly also was left in the TriggerLightProperties.

Tubelights that Flicker On

When a tubelight gets a little older, and you switch it on, it'll first flicker a few times before it's on. Using TexturePaletteOnce, you can make this effect in the game: first read the TexturePaletteOnce section if you didn't already. Now, make a new light class called "FlickeringTubeLight". Make a Skin for it: in PSP of PhotoShop or any other painting program that can edit palettes, make a palette like this:

With this palette, the light will first flicker a few times, and then at the end of this palette, it dies and so there should be no more light, but you're going to make a TriggerLight to go on at this moment.

Save this as a *.pcx file and import the texture into UnrealEd, and give it to Skin in Display in the FlickeringTubeLight's Default Properties. Don't forget to set bStatic = bNoDelete = False. Set LifeSpan to the time you want the tubelight to flicker, for example 2, and remember this value.

Now, add the SpawnThing at the location of the tubelight, set it's SpawnedActor to the FlickeringTubeLight, and it's Tag to for example TubeLightFlicker. Then, also add a TriggerLight at the same location as the SpawnThing, set it's Tag to TubeLightOn. Set the InitialState of the TriggerLight to TriggerTurnsOn. Now add a trigger with Event TubeLight, then add a Dispatcher with Tag TubeLight, and in Dispatcher --> OutDelays set [0] to 0 and [1] to the LifeSpan of the FlickeringTubeLight, in this example 2. Then in OutEvents set [0] to TubeLightFlicker, and [1] to TubeLightOn.

When you now activate the trigger, the Dispatcher makes the SpawnThing to spawn the TubeLightFlicker, that dies after 2 seconds, but exactly at that moment the Dispatcher activates the TriggerLight, so the tubelight is on and will never flicker anymore.

If you want to set the InitialState of the TriggerLight to TriggerToggle, then when you press the trigger again the TubeLight will go out only after 2 seconds, and before it goes out the TubeLightFlicker gets spawned another time. Possible solutions are: script something, or use a different trigger for turning the TubeLight on or off, the trigger to turn on with the same Dispatcher as described above, the other trigger with as Event TubeLightOn. You only have to make sure the player can NOT press the same trigger again without pressing the other trigger first.

Movers & Lighting

The following few sections require you to know something about movers. There's a tutorial on movers at http://www.perilith.com/~lode/tutorials/movers/movers.html

Movers have several properties that have to do with lighting: expand Mover in the Mover Properties.

  • bDynamicLightMover: If true, the lighting will be calculated for every place where the mover will be, so if it's first in a dark room and goes to a bright one, the mover will become bright as well.
  • BrushRaytraceKey: If the mover isn't a dynamiclightmover, the lighting on the brush will be calculated for this Mover Keyframe only.
  • WorldRaytraceKey: If the mover isn't a dynamiclightmover, the lighting around the mover (for example shadow of it) will be calculated for this Mover Keyframe only.

Fake Shadows

An example of the effect of WorldRaytraceKey is shown on these screenshots. The mover is a lift with two keyframes: Key0 is down, and Key1 is up. Of course this only works when bDynamicLightMover is False

WorldRaytraceKey = 0

WorldRaytraceKey = 1

The second shadow is calculated as if the mover was at its up position. You can also use this to create fake shadows.

Moving Lights

The Unreal engine supports moving lights: for example if you shoot a rocket, you see a shine of the light on the floor, ceiling and walls moving as well. Also the Flashlight and the Searchlight are moving lights, because you can walk around with them. However, there is no Moving Light class in UT that you can program to follow a certain path. The only way to make such a light, is to attach a normal light to a mover!

Most objects in UT don't give much difficulties to attach to a mover. To attach an object to a mover, you need to use an AttachMover instead of a regular mover. To get an AttachMover in UEd2, right click on the Add Mover button, and in the list that appears choose AttachMover. In the AttachMover's properties, open AttachMover and give an AttachTag. Now, open the properties of the object you want to add, and expand Events. In there, set the Tag to the AttachTag of the AttachMover.

Give the attachmover an AttachTag...
...and give the moving object the same Tag

You can also connect objects to movers that are not AttachMovers, for example normal movers, GradualMovers or LoopMovers. To do this, open the Movement tab of the object and give it an AttachTag, and set the Tag under Events of the Mover to the AttachTag of the object. This means using this technique, you give the object and AttachTag and the mover a normal Tag, while using the AttachMover technique, you give the mover an AttachTag and the object a normal Tag.

Give the object an AttachTag...
...and give the mover the same Tag

So this way works for most objects, but not for lights. Before the light will be able to move, you have to change some more settings: open the Light Properties and expand Advanced. In there change the following settings:

  • set bMovable to True
  • set bStatic to False
  • set bNoDelete to False

Change these three settings before the light can move

This is not only for lights, for each object you have to make sure bMovable is True and bStatic is False. Most objects have these settings like this already. These settings are self-explanatory: if bStatic is True, the object is a static object that will remain fixed on his position for ever. If bMovable is False, the object will not be able to move. So basicly these two settings do the same, the only difference is that the True of bMovable is equivalent to the False of bStatic, and vice versa.

The bNoDelete setting is a little more difficult.

  • If bNoDelete is True, the light is a static light that will be ray traced by the editor, and lightmaps will be created on the walls. This gives realistic lighting and shadows, but needs a lot of calculation time. The main reason you have to Rebuild lighting with the editor, is to calculate all these things and store it in the map data, so it doesn't have to be calculated when you play the map in UT. Realtime radiosity is not (yet) possible because the computers are still too slow. Moving lights require realtime calculation so they cannot use radiosity.
  • If bNoDelete is False, a much simpeler lighting algorithm is used, that can be calculated realtime while you play the map. This can be used for moving lights, however it is much uglier.

A light with bNodelete to True casts realistic shadows on High Shadow
Detail walls.
The same light and walls, but with bNoDelete to False:
a much uglier lighting algorithm.

If you have a moving light, but set bNoDelete to True, you get a really weird effect: the Unreal engine cannot calculate the moving shine of the light, so it uses a simple solution: only when the light is at it's begin position you see the light, and when it moves, the shine of the light on the wall disappears. With bNoDelete to False, you will see the lightshine does not disappear, but moves together with the mover.

Another detail about bNoDelete is that if bNoDelete is True (it's default value), the WorldRayTraceKey and BrusRayTraceKey of movers work proporly, but if it's False, these are just ignored. However that doesn't matter, as the light will move together with the mover anyway.

You can use moving lights for example to attach to vehicles, spaceships, trains or other moving things. But when you want a light to move on it's own, without vehicle or train, you can't do this without creating a mover. Then just place the mover outside the map, the light will still move together with the mover, no matter how far it's away from it.

Also, if you want the light to move forever, and not only when you hit a mover, you have to use for example a LoopMover, look at http://www.perilith.com/~lode/tutorials/movers/movers.html#looping for more details about this.

Moving Coronas

LightEffects like LE_Disco and LE_Rotor, and LightTypes like LT_Pulse etc... work with moving lights, even when bNoDelete is False. Also Fog works when the light is a moving light, try it out because moving fog looks great! You can use this for example for realistic foggy clouds moving around.

However, Coronas give some problems! First of all, when you add a corona to a light with bNoDelete to False, and rebuild lighting, the corona will not appear. There is a way to get around this! To do this, first set bNoDelete of that light to True and rebuild your whole map. Because bNoDelete was True, the corona is there and everything is just fine. However after that, set bNoDelete to False and do not rebuild anymore, but just save your map. The corona will remain there and also work in the game. You will have to do this every time you want to play the map, and the most important moment to do it is just before you release your map. You don't have to do all this if you use seperate lights for the corona and the shine: the coronalight does not have to be bNoDelete = False, because you don't need it's shine and set it's LightBrightness to 0.(see also a little further)

This was only the first problem. The second problem is a lack of support from the Unreal engine. Coronas work like this: there is a certain radius, determinated by the LightRadius setting. Only if you are inside that radius, you see the corona. Now here is the problem: this Corona Radius does not move together with the light! This means, if you have a light that moves together with it's corona, you can see the corona as long as you stand in the beginposition of the light, even if the light is 25 kilometers away. But when you move together with the light, you move away from the center of the CoronaRadius that stays on the beginposition, and you will not see the corona anymore, even if you stand on the same place as the light's current position.

What is the solution for this? Use a seperate light for the corona and the shine, and give the light with corona a LightBrightness of 0 but a huge radius. Set the radius of the other light to a normal radius, and give it no corona. (You can also read this at the end of the Corona section). The radius of the corona is most of the times big enough to work for very large distances. An advantage of this technique is that you don't have to set the bNoDelete of the coronalight to False, so you don't have to solve the first problem.

There's a working moving corona in the example map.

Scale Lights

In the Tools menu, there's a tool called Scale Lights.

Select one light and open it's Light Properties, expand LightColor (you don't have to do this, but do it now so you can see the value changing). Now open Scale Lights... in the menu Tools. Enter a Literal Value of 100. Make sure you can see the LightBrightness in the light properties. Press OK in the scale lights window and look at the LightBrightness changing. Every time you press Ok, it changes: it becomes 100 brighterer exept if it will become more than 255: then it will be dark again.

If you enter a Percentage of 100, the LightBrightness is multiplied by 2 every time you press OK. If it's 50, it will be multiplied by 1.5, if it's 20, by 1.2, etc...

You can also enter negative values, to make the lights darker.

The advantage of this tool is that, if you select 2 or more lights, and use the tool, the lightbrightnesses are calculated independent for each light. So if one of the lights had a brightness of 50 and the other one of 80, and you entered a literal value of 20, the first light will become 70 and the second one 100.

This tool might be useful if you have a room with lights with different lightbrightness and you want to make them all a little bit brighter. Just select them all and use the tool.

Light through Solids

Light doesn't go through solid or semisolid walls in the Unreal Engine (duh). But it also doesn't go through translucent or masked walls. It only goes through non-solids, but then you can walk through the wall or window or fence or whatever. If you want light to go through a solid or a semisolid wall, there is a complicated way to do that:

If you have for example windows with glass in them and want the light from outside (for example lightnings) to go through it, make the glass a mover, set it's key0 to it's normal place in the window and key1 on a place far away from it. Set WorldRayTraceKey to 1 and set it's InitialState to TriggerToggle and enter a unique tag for the brush. Do not create a trigger for it. This way, the mover will never move. Now, rebuild lighting: the light will be calculated as if the window is on that other place far away, so the light WILL go through the window.

Light through Non-Solids

Light goes through non-solid walls, but the only problem is that you can walk through these walls. However, sometimes you have a situation in which it doesn't matter that you can walk through them. For example if you create lanterns. To do this, make a brush that looks like a lantern and place it at the right location, open the Brush menu, choose Add Special... In the window that appears, set Prefabs to Regular Brush and set Solidity to Non-Solid. Then press Ok.

The Add Special Brush window

Now, add a light and place it inside the non-solid lantern. Rebuild geometry and lighting, and you'll see that the lantern gives light. If it was solid or semisolid, the lantern would not have given light.

A nice thing is that you can also see the corona of the light, if it has one.

The map DM-Gothic uses non-solid lanterns.

Searchlight, Flashlight and Flare

In the Actor Class Browser --> Inventory --> Pickup, you'll find Flashlight and Searchlight. These are the old ones from Unreal 1.
If you place them in an UT map, and a player picks them up, they work! This can add a lot of value to maps, it's really cool in dark caves etc...

The SearchLight shines better and has longer battery power than the flashlight.

The SearchLight and the FlashLight.

Translucent Surfaces

If you have a translucent wall, you can make it more/less translucent by giving it much/little light. Use special lit if you don't want the enviromnent to be affected by this. A translucent surface that is not illuminated at all, will be invisible.

The same counts for Modulated textures, only they will become black if they are not illuminated at all.

Every time the same texture, getting less translucent when it receives more light.

Coronas in a Skybox

If you place coronas in the skybox, you can not see them in the game. Th UT engine just doesn't support that. The best way to get a fake corona in the skybox, is to make the light a 2D sprite (go to section Sprites for this), and set Style in Display to STY_Translucent. In the map, you can't see that it is a fake, because you are not able to move closer or further away from it.

Lightnings

In the Actor Class Browser choose Light --> DistanceLightning. This is a light that flashes about every 30 seconds, like a real lightning. If you want lightnings in your map, use these.

Always place them in the skybox, so the clouds get the effect of the lightning, but you also have to place some in the map itself to enlight that as well. You can create cool effects with lightnings through windows, if you set floor and walls to High Shadow Detail.

ThunderLightning

For this section, I assume that you know something about scripting, if you don't know anything about it you can destroy your UT if using it wrong.

Lightnings never appear without thunder. There are a lot of ways to create thunder, in the first place by adding a Sound actor, however it will make the thundersound every second and that is too often.

Many people have found a way around this with scripts or trigger systems. I tried this as well: I made a new actor called ThunderLightning. It is a the lightning and the sound together in one actor. Actually I copied the DistanceLightning's script and just added a few lines in it.

To get a ThunderLightning yourself, do the following:

First open the actor class browser and select Light. Then in the menu Class choose New.... The New Class window appears. First of all make sure that the Parent is Light. Use a packagename that does not exist already, or you'll destroy that package of your UT. The best Package name to use is MyLevel, because this way you don't have to create a seperate *.u file together with your map. However, if you want to use the class in multiple maps without making this script every time again, choose another name. As Name use for example ThunderLightning.

The New Class window

Right click on the new class and choose Edit Script, you now see the Script Editor.

The Script Editor

Enter the following script:

//=============================================================================
// ThunderLightning.
// Edited version of DistanceLightning, by Lode Vandevenne
//=============================================================================
class ThunderLightning expands Light;

function BeginPlay()
{
SetTimer(5+FRand()*10,False);
LightType = LT_None;
}

function Timer()
{
if (LightType == LT_Flicker)
{
LightType = LT_None;
SetTimer(9+FRand()*20,False);
}
else
{
LightType = LT_Flicker;
PlaySound(Sound'AmbOutside.OneShot.thund1', ,255.0, ,6400.0);
SetTimer(0.8+FRand()*0.5,False);
}
}

After this, change the following default properties of your new class. Right click on the class and choose default properties.

  • set bStatic to False in Advanced
  • give it a LightBrightness and LightRadius of 255. You can make the radius seem larger if you use LE_Cylinder
  • set LightType to LT_Flicker

Compile you script: in the Script Editor's menu Tools choose Compile Changed. Before you compile, make sure you have loaded the soundpackage (in this case AmbOutside) that contains the thundersound, or the compiler will give an error.

If you gave another package name than MyLevel, you have to save your package as a *.u file. In the menu view of the Actor Class Browser select Show Packages, and in there select your newly created package (not any other one, or you'll destroy UT) and in File of the Actor Class Browser choose Save Selected Packages.

If you distribute your map, don't forget to include the new *.u file you created in the system folder (of course not necaissary if you used MyLevel.)

You can also have it to make another sound, open the sound browser and in there open AmbOutside. There in OneShot are Lightn and Thunder sounds. To know what you have to enter in the script, create a light and set it's AmbSound to this. You'll then see the name of it. Copy that name, and enter it in the pre-last line of the script, between the ' '.After that, remove the light again.

When this actor is ready, it's very simple to make a map with lots of lightnings and thunders by just placing ThunderLightnings everywhere in your map!

This is only one way to make lightnings and thunders. You can also do this by using a combination of stochastic triggers, distance lightnings, triggered lights and triggered sounds. There's a great tutorial on storms, lightnings and thunders by Darendash, at http://members.home.com/darendash/AdvancedLightning.html and there's another script for this at http://www.planetunreal.com/unrealed/tutorials/adv/storm/

Visible Lightnings

Adding visible lightnings to the skybox gives really cool effects.

Lightnings in the skybox

To make them, you will need to import a masked lightning texture first.
Make a skybox in your map, and add some vertical sheet brushes in it, and give them the lightningtexture. Now, you want the lightningtexture to be visible only at the moment the lightning strikes. At all other moments, they must be invisible. To do this, do the following:

  • Open the surface properties of the lightning
  • Set the surface to Translucent, and also to Special Lit
  • Now add one or more DistanceLightning actors close to it (It's in the Actor Class Browser --> Light --> DistanceLightning)
  • Open the properties of the DistaceLightning and expand Lighting
  • In there, set bSpecialLit to True and also give it a smaller radius.

Also make sure that there is no ZoneLighting in the SkyBox, and there are no other special lit lights.

This way, the lightningtextures will not be illuminated by any other lights than the DistanceLightnings, so as long as the DistanceLightning does not strike, the lightningtextures don't get illuminated and will be invisible.

There is one small problem with this: if you want the clouds of the sky be illuminated at all time, you cannot set it to Special Lit, but this way it will not get illuminated by the lightnings! The solution for this is to add a large horizontal sheet brush very close to the clouds, give it the same texture as the clouds, and set it's surface properties to the same as the lightningtextures. This way, you have a new layer of clouds that looks exactly the same as the original clouds, and will be visible only when it gets illuminated by the DistanceLightnings.

One thing: these lightnings will look horrible if MultiTexture is disabled in the Direct3D settings (read more about these settings in the section Fog)

These screenshots show the difference between MultiTexture disabled and enabled. Make sure you enable it!

MultiTexture disabled

MultiTexture enabled

Is My Map Too Dark?

Sometimes it's very difficult to know when your whole map is too dark or too bright. The ligthing of your map can add a lot to the atmosphere, so some maps need to be brighter or darker according to their theme. However, making a map TOO dark can ruin a good map. You can never be sure if your map is too dark or not, because every player has his own monitor settings, gamma setting (press F11 in the game to make the gamma brigher or darker), etc..., so a map that looks bright/dark on your pc might look very dark/bright on someone else's pc.

What you can do is, first of all look at the official maps included by Epic. These have a correct global lighting. Just pick a map that has about the same atmosphere/theme as your map, remember the global lighting of that map and try to put that into your map by altering the ZoneLight a bit, or making all the lights brighter or darker.

Also let some other people betatest your map and ask them if they find it too dark or too bright.

Lighting Tips

  • Together with texture aligning, correct lighting is one the elements that are difference between a professional looking and a bad looking map!
  • Do not exaggerate using special light effects, flashy colors etc... Dynamic lights slow down computers and too many colored lights (with saturation = 0) can make people nuts.
  • Use LightSources! Place lights, lanterns, tubelights, etc..., in your rooms, this adds a lot of realism to the map. The light must come from somewhere!
  • Use coronas: they look really nice, and make your lightsources even more realistic.
  • Don't make your map too bright or too dark. Add variation in your map: a dark corner in a bright room, a sunny outdoor area with a dark cave, etc...
  • If you are using multiple lights for something identical, for example a room with 24 tubelights in it, you can place these lights in a unique group (it's in the object properties of the light). If you want to change something for all the tubelights at the same time, it's much easier to select all these lights at the same time by making only their group visible. Use the group browser then to manage your groups.
  • A map isn't professional or cool because it has a lot of weird lighteffects or colors in it. A lot of moving stuff and colors can make people nuts while playing the map. Keep the effects subtle!

The Example Map

A screenshot of the example map. With multiple rooms visible, and that's what makes the screenshot so ugly.

I've included a large example map in this tutorial, called DM-LightingDemo.unr. It's included in the zipped version of this tutorial. If you open it in UT, make sure there are no bots, they are really annoying! Also make sure Volumetric Lighting and ScreenFlashes are enabled.

Here's a description:

Once you are in the map, you are in a large outdoor environment, with a storm. You will hear thundersounds, because I added some ThunderLightning classes in there, and if you wait a little bit you will see lightnings in the sky. In front of you is a large building, the entrance is indicated by two green lights.

If you enter the building, you are in a large dark room. A trigger will activate all TriggerLights on the ceiling, making it very bright.

The next room is a dark room, with a green strobing blacklight in it. That's why the Nali's and the trees are strobing like that.

After that, you enter a small corridor with a broken tubelight in it. If you listen you will hear the flickering sound of it.

At the end of the corridor is a foggy room, and after that there is a room with moving lights in it. Some of the moving lights have Volumatric Lighting, so it looks like a moving cloud. There's also a moving corona.

Walk on the stairs, and enter the next room. There is a window with light shining through it, casting a nice shadow on the floor and the walls. If you wait a few seconds, you will also see the lightnings through it.

Walk on some stairs again, and you enter a room with lava in it. The lava looks so bright because it's surface propertie in Unlit, and there's a light with a fireeffect.

The next room shows an example of the use of special lit: some of the walls are illuminated by a blue light, the others by a red light. After that you enter a discobar, with a discolight in it, that changes color because it's LightType is TexturePaletteLoop and it has a colorful candy skin.

There is a door in this disco room, and if you go through it you enter a room that looks exactly the same as the castles of the old game Wolfenstein3D. It even has 2D objects in it, just like that old game had, and there's no lighting at all: everything is Unlit. There is a lift. To make the lift go up, stand close to it's wall with switch. To make it descend, move away from the switch.

Once you are up, you enter a room with some rotating coronas in it, and there is a fire.

In the next room you see green rings on the wall, created by lights with LightEffect LE_Shell, but if you enter the room, your screen suddenly turns blue. That's because there is a Zone with ZoneFog in the room.

After that you see a room with lightboxes.

If you go up the stairs you enter a green room, and on the right you see a dark corridor. There's also a FlashLight on the floor. If you pick it up, you can use it to walk in the dark corridor.

Once you are out of the corridor again, use the stairs to go to the next room, with a lot of translucent windows in it. The first one are hardly visible, while the last one is almost completely opaque. This is because the first ones almost don't get any light, while the last ones have a really bright light next to them.

As a bonus, you now can use the stairs to go to the roof of the building, and then jump off the building.

Download

This zipfile includes the html, all screenshots and the example map. It is 2616 KB.

lighting.zip

What's new?

Version 1.45 (August 13th 2001)

  • figured out LT_TexturePaletteOnce and added a section about it.
  • added the section "TubeLights that Flicker On".
  • again some minor improvements

Version 1.4 (July 31st 2001)

  • corrected more than 30 typos and spelling errors
  • slightly changed layout
  • added section Fake Shadows
  • added section Is My Map Too Dark?
  • added new screenshots to old sections
  • improved some old sections, for example ZoneLight
  • installed UnrealEd1 again, so I could make some UEd1 things more clear
  • added more Lighting Tips

Version 1.31b (July 26th, 2001)

  • the smallest improvement ever
  • old host simpletown went down. New URL is http://www.planetunreal.com/lode/lighting/lighting.html

Version 1.31 (February 2001)

  • some minor improvements

Version 1.3 (February 2001)

  • added example map, DM-LightingDemo.unr
  • added section BlackLights
  • added section Visible Lightnings
  • added section Bright corners
  • added section More ZoneLight Properties
  • removed section Brushes that give light (they only work in the editor)
  • some small enhancements

Version 1.21 (January 14th, 2001)

  • deleted the Attaching lights to a mover section
  • deleted all the wrong/incomplete info of the Moving Lights section
  • combined these two sections into one new Moving lights section, with a lot of new info and added screenshots to it.
  • added section Moving Coronas

Version 1.2 (January 7th, 2001)

  • added two new sections: Lightnings and Coronas in a SkyBox
  • corrected some minor mistakes
  • added more screenshots

Version 1.1 (December 2000)

  • corrected a lot of mistakes (thanks to all the people who emailed me), made some things more clear
  • added sections Light through solids, Light through non-solids and Translucent surfaces
  • updated LightingTips section
  • added subtitles to the screenshots
  • gave the tutorial larger screenshots. This means more downloading time, but the small screens were not clear enough.
  • added support for UT v436, because this update changes some important things about the editor.
  • added new screenshots

Version 1.01 (September 2000)

  • added section ZoneFog
  • corrected some minor mistakes

Version 1.0 (September 9th, 2000)

  • first released version

Version 0.0 (August 11th, 2000)

  • creation of this tutorial started

Contact

Please contact me if you have any suggestions, questions, problems, or whatever: email it to lode@altern.org

(c)2000-2001 Lode Vandevenne. Do not copy/translate any of the content of this tutorial to a site/book/whatever without my permission.


BB Drac - Unreal Tournament UED2 guide Light sources

Light Sources

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Light in UT comes from light sources.
To add a light source just press right mouse button and
select "Add Light Here".
You will see a torch looking like this added to your design;
UED2 Torch Image

The easiest way to add a light is in the 3D view and then use
the 2D view to move the light around.

Lights (like all stuff in UT) use processing time in-game.
Using lights effective will keep frame rate at best.

Alot of light related info can also be found in my texture/wall
tutorial.

Light properties is explained in the tables below.

Property | Specific
+Advanced |
bDirectional | Make the light directional (used with spotlights).
+Display |
DrawScale | Affects light actor size in editor and size of lensflare.
Skin | The texture used for a lens flare and TexturePaletteOnce/Loop effect.
+LightColor |
LightBrightness | How bright the light should be from source and outwards.
LightHue | Light color (also affected by LightSaturation)
LightSaturation | Light color (also affected by LightHue)
+Lighting |
bActorShadows | Creates shadows (bShadowCast).
bCorona | Adds lensflare to the light (needs texture, Skin).
bLensFlare | Not used by UT.
bSpecialLit | Light only affect walls and items with the Special Lit true.
LightCone | Size of specific lights, like spotlights.
LightEffect | Select how the light is supposed to act (Further down for specs.).
LightPeriod | Speed of selected LightType and/or LightEffect.
LightPhase | Start of light animation cycle.
LightRadius | Radius affected by the light and lens flare.
LightType | What kind of light (Further down for specs.).
VolumeBright | Brightness of volumetric light (fog).
VolumeFog | Thinkness of columetric light (fog).
VolumeRadius | Radius of volumetric light (fog).

Light Effect | Specific
TorchWaver | Makes the light shimmer a little.
FireWaver | As the TorchWaver but more "drastic".
WateryShimmer | Also like the TorchWaver but more wave and glimmer feel.
SearchLight | A rotating spotlight (Adjust speed with LightPeriod).
SlowWave | A wave that starts from the middle and flows out.
FastWave | As SlowWave but at a faster rate.
Shock | A small pulsating light, fast up and slowly down.
Disco | What can I say, weird looking disco light.
Spotlight | Simply a spotlight (set bDirectional).
NonIncidence | Makes the light stronger and reduce the amount of shadow.
Shell | Only lights the actuall lightradius (a hollow sphear).
OmniBumpMap | This a light that only light up actors(players) and not the geometry.
Interference | Light waves that goes from bottom to the top.
Cylinder | Creates a light cylinder instead of a standard sphere.
Rotor | Like Interference but moves sideways instead, like a fan.

Light Type | Specific
None | Turns the light off.
Steady | The light "strength" is constant (Default).
Pulse | A "heavily" pulsating light.
Blink | Randomly turns light off for a split second.
Flicker | Randomly turns light on/off at random intervals.
Strobe | Fast switching between light on and off.
SubtlePulse | As Pulse but less "deep".
TexturePaletteOnce | Will cycle through the texture palette selected for "Skin", once.
TexturePaletteLoop | As TexturePaletteOnce but loops (Adjust speed with LightPeriod).

Changing the color:
When you select either LightHue or LightSaturation a button "color" will show.
Press this button and select a color you want.
This will be the color your light radiate.

 Adding a Lens Flare (Corona):
To do this you need to set "bCorona" under "Lighting" true.
You also need to add a texture to "Skin" under "Display".
"DrawScale" under "Display" adjusts the size of the lens flare (0.2-0.5).
Just note that you are not able to see coronas outside the light radius or
through/past zones.

 LightPeriod and LightPhase:
LightPeriod sets the speed of animated lights, like searchlights and so on.
LightPhase however change the frame which your animated light should start
from.
It can be used to sync two lights with the same light effect,
or the light with a mover to make sure both objects move/animate the same.
(A rotor mover and a light with the rotor light effect).

 Shadows:
To do this you need to set "bShadowCast" under "Display" true for the item.
Also set "bActorShadows" under "Lighting" true for the light to create the shadow.
(Didn't get this to work).

 Creating a spotlight:
The spotlight is directional so you need to set this property.
It is found under "Advanced" and "bDirectional"
Then change the "LightEffect" under "Lighting" to "Spotlight".
You might want to adjust the direction your light is pointing though.

 DrawScale:
If the "DrawScale" property is not used for a lens flare you should
use it to make your editing easier.
In large outdoor areas you might want to use a draw scale of 5.0.
In small areas with lots of light sources 0.5 is maybe small enough.

 TexturePalette Loop and Once:
This is a light type that cycles through the light color using a texture.
Any texture will work, but alot of palette and fading textures can be found
in "palettes.utx" and "genfx.utx".
The texture must be added to the propery "Skin" under "Display" for the light.
LightPeriod will then adjust the speed to the color cycle.

 Alternative lightsources:
Anything that has the properties "+Lightcolor" and "+Lighting" can
radiate light.
Just change the light properties to suit your need.
(Not sure that exactly everything can).

 Default light levels (zonelight):
You can use zoneinfo actors inside zones, or level properties if
you do not use zones, to give areas or the entire level a default
lighting. (Particulary good for out door areas).
Under "ZoneLight" you can adjust "AmbientBrightness", "AmbientHue" and
"AmbientSaturation" to adjust the default lighting, much like a normal
light.

 Soundeffects and light effects:
If you add ambient sound to a lightsource it will be heard as long
as the light is on.
If the light is "LE_Steady" you can hear the sound all the time
while lights with other effects like "LE_Flicker" will turn on/off the
sound along with the light effect.
This allow you to create more realistic and syncronized lights and sounds.
Triggerable lights: In the actor browser, under "Light" you have "TriggerLight".
(Two actually, but both are the same).

They work exactly like regular lights with one slight differance.
Regular light cannot be triggered while these can.

TriggerLight | Specific
bDelayFullOn | If true, the light will wait "ChangeTime" before changing state.
bInitiallyOn | If the light should be on or off.
ChangeTime | Time in seconds to change/fade from on to off (or off to on).
RemainOnTime | It is connected with "TriggerPound" but I didn't get it to work.

The "InitalState" of the light determine how the trigger should affect the light.

InitalState | Specific
None | Useless as the light will not be affected by trigger.
TriggerPound | Don't know if work
TriggerControl | Light will stay on/off as long as player is in trigger radius.
TriggerToggle | Turns off the light if it is on, and on if it is off.
TriggerTurnsOff | Deactivates the light (nothing happens if light is off).
TriggerTurnsOn | Activates the light (nothing happens if light is on).

Volumetric Light (fog):
To create fog you use lights.
The three properties "VolumeBrightness", "VolumeFog" and "VolumeRadius" set the brightness,
depth and size of the fog.
VolumeRadius is the covered sphear of the fog while VolumeBrightness and VolumeFog
both set the density.

Other light types and decoration:
In the actor browser you will find lots of lights and light decoration.
Most actors under "Light" is just regular lights with pre-defined properties.
"TorchFlame" is a ready to use lightsource unless you want to create your own
flames.

Under "Decoration" you will find actors that can aid your level theme.
This includes "LightBox", "LightCone", "TubeLight" and so on.


BB Drac - Unreal Tournament UED2 guide Advanced Lights, Triggered

Triggered Lights

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

You have probably seen it in other games or sci-fi movies.
Whenever someone opens a door or enter a hallway or large warehouse
all lights lit up one by one, but not before they flicker some first.

This looks very cool, but how do you do this in UT?

In this tutorial I will show you how to create and use triggered lights
to first create a flicker light and then goes steady.

To be able to follow and understand this tutorial it is important that
you understand lights, movers and triggers.

The first thing to explain is that we cannot use regular lights to create
the effect we want.
Regular lights radiate light all the time and cannot be triggered.
In the actor browser under "Light" you have "TriggerLight". This is what
we need to use, instead of regular lights.
They work the same way but can be triggered on/off.

In this tutorial you can create any design you want but keep in mind that you need
at least two different light sources.
From the picture (below) I have created one small starting room connected
with a small hallway through a door.
Screenshot

Now, how do we put all this into action?
First of all. Place two "TriggerLight" close to each other for each light source.
(You should only use two light sets or you need to do some changes).

The reason we use two "TriggerLights" for one light source is that one of them
will be "Flicker" and the other "Steady".

Change the properties for each light as listed:
Light Set 1, Light 1, Tag: Light_1A
Light Set 1, Light 2, Tag: Light_1B
Light Set 1, Light 1, LightType: LT_Flicker
Light Set 1, Light 2, LightType: LT_Steady
Light Set 2, Light 1, Tag: Light_2A
Light Set 2, Light 2, Tag: Light_2B
Light Set 2, Light 1, LightType: LT_Flicker
Light Set 2, Light 2, LightType: LT_Steady

Also make sure that all properties under "TriggerLight" are false, false, 0 and 0.
Under "Object", "InitialState" must be "TriggerToggle".

By Light Set I mean the pair of lights for each lightsource.
By Light 1/2 I mean the first or second light in the Light Set.
By light source I mean the visual (texture) light which players see.

Now our lights will start black and the hallway will be black as well.
These lights need to be triggered and as there is four lights we need a
"Dispatcher".
Select it from the actor browser under "Triggers" and place it somewhere in the level.
Change the tag of this "Dispatcher" to "LightActivate".

Now to add all the lights to the dispatcher trigger set.
Under "Dispatcher" add; Light_1A, Light_1B, Light_1A, Light_2A, Light_2B, Light_2A
to "OutEvents[]".
To "OutDelays[]" add; 0, 1, 0, 1, 1 (the rest should be zero).

This dispatcher will now trigger the lights but we also need something to trigger
the dispatcher.
In this example I use the mover to easier show how to toggle the lights on and off.

For the "Events" and "Event" type "LightActivate".
Also change the "StayOpenTimed" under "Mover" to 12.

If you add a player start and play the level you can see how good this looks.

This is how it works:
When the door opens it will trigger the dispatcher.
The dispatcher will trigger the first light (Light_1A) which is a flicker type
and will be active for one second.
Then the second light (Light_1B) will be activated and the first light deactivated
(Light_1A).
Then, one second later, the other light set will be activated the exact same way.

When you open the door the second time it will do the exact same thing but
the steady lights will be turned off in the end.

All in all it will give the player the illusion of one single light flickering alot
before it turns steady.


BB Drac - Unreal Tournament UED2 guide Advanced Lights, Timed Triggered

Timed Triggered Lights

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

This light tutorial will show you how you can use timed triggers and
dispatchers to create a small lightshow.
Maybe not as good as a true disco, but good enough.

To be able to follow and understand this tutorial it is important that
you understand lights and triggers.

I will start with the image for this tutorial.
Screenshot

The design is simple as it is a large room with two mirrored walls on the sides.

For the lights I have used "TriggerLights" found under "Light" in the actor browser.
In this example a total of five was placed.

All lights have different lights effects, like disco, interference, rotor and
some with textureloop.
(What effect, light radius and brightness isn't really important).

Now all lights are initially off and initial state "TriggerToggle".
They have also been given unique tags (L_Disco, L_Strobe, L_Rotor and so on).

Now to the interesting part.
For each light I have placed one Timed trigger and one dispatcher.
Each timed trigger activate at different time intervals to make sure that
not all lights lit up at the same time.
The timed trigger will trigger the dispatcher which only activate the
light and then let it stay on for a few seconds.

The timed trigger must have the event to the dispatcher tag and the
dispatcher will only activate and deactivate one light.
That is why I have placed five timed trigger and dispatcher for five lights.

As a result you will get lights that light up at different times and stay on only
for a few seconds.

Kind of useless unless you are creating a disco.
You did, hopefully, get the grip on timed triggers and different light effects.


BB Drac - Unreal Tournament UED2 guide Advanced Lights, Destroyable

Destructible Lights

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

How realistic is a light if you are unable to destroy it?
And that even if you are sending a warhead on it.

This tutorial show you how this could be done.

To be able to follow and understand this tutorial it is important that
you understand lights, movers and triggers.

Simply said, we use a mover for the actual light gfx, a trigger light
for the light itself and a breaking glass for the shards.
Screenshot

The design is simple. A small room with no standard light sources.

The first thing to do is to add two movers with different textures
on each side.
On the first side, which is the side we see when starting the level,
I used a regular light textures from "playershp.utx".
On the other side I used a broken version of the same texture.

The mover is triggered by damage and have initial state "TriggerControl" and
"bTriggerOnlyOnce" true.
For keyframe 1 I simply rotated the mover so that when triggered it will show
the other side instead, which is the broken light texture.
Therefore it is important that "MoveTime" is zero and "bDynamicLightMover" is true.

The event of each mover is unique as they will trigger different lights.
Type "LightDestroyed1" for "Events", "Event" on the first mover and "LightDestroyed2"
for the second.

Add a TriggerLight (found under "Light" in the actor browser) and place one in front
of each mover.
Change the tag to "LightDestroyed1" for the first light and "LightDestroyed2" for
the second.
Also make sure that both are "bInitialOn" True and "InitialState" "TriggerTurnsOff".

Now we have the light and actual light.
For the shattering we need the effect "BreakingGlass" found under "Effects" and
"ExplodingWall".
Place one in front of each mover.

Change the following properties for both actors:
BreakingGlass, NumParticles: 4
BreakingGlass, ParticleSize: 0.3
Collision, bCollideActors: False
Collision, bCollideWorld: False
Collision, bProjTarget: False
Effects, bOnlyTriggerable: True
ExplodingWall, bTranslucentGlass: True
ExplodingWall, bUnlitGlass: True
ExplodingWall, GlassTexture: [A glass texture, maybe from genin.utx]

Also check that each Breaking Glass actor have "LightDestroyed1" or "LightDestroyed2"
in the Tag.

Now, this should be enough.
Try it and see what true lights should be like.

This is how it works:
The mover works as the trigger and will be activated when damaged.
This means that you can "destroy" the lights from any angle, as long as you
hit the mover.

The mover turns around, showing the broken light texture instead, and triggers
the event.
Both the light and breaking glass actor will be triggered resulting in the
shutdown of the light and a few shards falling on the ground.

This is, as it have been done, an irreversible effect and might not be such
a good solution to use at all lights in a level as it will turn out pretty dark afterwards.


How To Make TriggerLights

by: Cralex NS
cns@planetunreal.com

How to make TriggerLights?

(Note: I hope you can understand if not ICQ#91846003 me. This tutorial is for experienced UED users)

Ok, make your map and the lights you want to be turned on/off by a switch. Make the light (brushes) and open up the Class Browser

Find: LightTriggerLight (there are 2 of them, it dosnt matter wich one you choose)

Now add one of those at each light brush, setup their lightning properties and it should look something like this:

Now open up the properties for your TriggerLights again and expand TriggerLight and set bInitiallyOn to `true`

Expand Object and set InitialState to TriggerToggle
Last expand Event and then set Tag to `light`

Now the lights are fixed so build a switch somewhere (brush) and open up the Class Browser, expand triggers and add a trigger
Set the Event > Event of the trigger to `light`

And set Trigger > ReTriggerDelay to `1`

Rebuild your map, and test out the triggerlights, if they doesn`t work go back to the start of this tutorial and check if you missed something.

Effect Step 1:
(If you are having more sets of lights, 2x2x2 or 2x2 like on the picture in this tutorial, effect step 1 and 2 will be nice.)

Now, it works a bit boring doesn`t it? We want some nice effect on the triggerlight so lets make that right now :)
First, open up 2 of your lights properties and expand Event and set Tag to `light2` and the other set of lights to `light3` and if more just go on.

Now, open up the Class Browser again and expand Triggers, add a Dispatcher somewhere around your trigger
(it doesn`t matter where, but keep it somewhere around so you know it belongs to the lights)

Open up the properties of your Dispatcher, expand Event and set Tag to `lightcon`
Now expand Dispatcher, expand OutEvents and set [0] to `light`, [1] to `light2`, [2] should be `light3` and so on, if you got more sets of light.
Then expand OutDelays, set [0] to `0.5`, [1] to `0.5`, [2] should be `0.5` etc. (now 0.5 is just an example 0.2 or 0.3 would be nice too)

Last set the Event > Event of your trigger to `lightcon`

Rebuild your map and test out the new nice effect. The lights turn on/off could get more advanced but lets just goto making them feel real, adding sound to them!

Effect Step 2:
Open the Class Browser, expand triggers and add a SpecialEvent for each set of lights you got.

Set the first SpecialEvent`s tag to `light` and the second to `light2`, third to `light3` etc.

Select all the SpecialEvent`s expand SpecialEvent, press the sound field and select a sound for your lights when they turn on/off

(A lot of click sounds can be found in Activates.uax)

Now Expand Object and set InitialState to PlaySoundEffect.

Now, rebuild your map and enjoy the great feeling of switching lights on/off with a really cool effect, and fell of real :)


Alarm Lights

By: IceLord (NL)

icelord_nl@hotmail.com

UnrealED 2.0 Tutorial:

A CTF-base without alarms is like the Pentagon without any security. A CTF-base just has to have some sort of alarm-system to alert the defenders BEFORE any flags are being robbed, right?

Okay that is what this tutorial is all about: making alarmlights.

As promised be myself, this time I did all the scripting myself. Now I truly understand that scripting can sometimes be a real pain in the…, you know what I mean J.

The concept of the AlarmLight:

To explain the concept of the AlarmLight I have provided an example map.

In this map, there are 3 areas. One area is the Red Base, one area is the Blue Base and the last area is a Neutral Zone. Each area has its specific lights (red lights for the Red Base, blue lights for the Blue Base and normal lights for the Neutral Zone)

Just play the example map once (just follow the instructions below). Don’t forget to chance teams at least once, so you can turn those screaming alarms off (or on!!!)…

- Copy the example map to your \UnrealTournament\Maps directory and startup UT.

- Start a Practice Session, set the GameType to Capture the Flag, select CTF-AlarmLightExample as your map, set the number of bots to 0, and click on Start…

As you have seen: if you are playing as a member of the RedTeam and you walk into the Blue Base the alarm will be triggered. You can also occupy the Neutral Zone and turn it into a RedTeam controlled area. Above that, you can turn off the alarms in your own base (it will stop the annoying alarm).

Vice versa: if you are playing on the BlueTeam the alarm in the Red Base will sound when you enter their base and you can occupy a Neutral Zone and turn it into a BlueTeam controlled area, etc…

The concept of an AlarmLight is pretty simple, all I needed in this example is:

· A Movers (Tag is irrelevant, Event = AlarmLightX)

· An AlarmLights (Tag = AlarmLightX, Event = None)

The AlarmLight works like this:

When a player bumps the mover, the mover will activate the AlarmLight. The AlarmLight will then “scan” to see which team the instigator is on. If the AlarmLight is ”neutral”, than the instigator will get control over the Alarm, turning the light into a calm blue light or a red light. If the AlarmLight is on the same team as the owner, the alarm will be turned OFF. If you trigger an AlarmLight that the enemy owns, the Alarm will be turned ON.

The AlarmLight:

Before we can add any AlarmLights to our level, we first have to do some scripting.

Just follow me:

1. Startup UnrealED 2.0

2. Open up the Actor Class Browser à Light à TriggerLight

3. Rightclick mouse à New…

4. Package: MyLevel

Name: AlarmLight

5. Copy the following lines into the script (overwriting all the text there is):

//=============================================================================

// AlarmLight.

// Made by IceLord (NL)

// Version 1.0 - NOTES : AlarmOnEvent and AlarmOffEvent are in-operational!!!

//=============================================================================

class AlarmLight expands TriggerLight;

// Variables

var()   enum TeamColor {TC_Red,TC_Blue,TC_Green,TC_Gold,TC_None} TeamOwner;

var()   byte InitialBrightness; // Initial brightness when nobody is Owner

var()   byte InitialHue; // Initial hue when nobody is Owner

var()   byte InitialSaturation; // Initial saturation when nobody is Owner

var()   byte RedBrightness; // Brightness when RedTeam is Owner

var()   byte RedHue; // Hue when RedTeam is Owner

var()   byte RedSaturation; // Saturation when RedTeam is Owner

var()   byte BlueBrightness; // Brightness when BlueTeam is Owner

var()   byte BlueHue; // Hue when BlueTeam is Owner

var()   byte BlueSaturation; // Saturation when BlueTeam is Owner

var()   byte GreenBrightness; // Brightness when GreenTeam is Owner

var()   byte GreenHue; // Hue when GreenTeam is Owner

var()   byte GreenSaturation; // Saturation when GreenTeam is Owner

var()   byte GoldBrightness; // Brightness when GoldTeam is Owner

var()   byte GoldHue; // Hue when GoldTeam is Owner

var()   byte GoldSaturation; // Saturation when GoldTeam is Owner

var()   sound AlarmSound; // The alarmsound

//
var()    name AlarmOnEvent;
// Event when alarm is triggered by enemy

//
var()    name AlarmOffEvent;
// Event when alarm is triggered by enemy

var     byte TeamOwnerBrightness;

var     byte TeamOwnerHue;

var     byte TeamOwnerSaturation;

var     byte AlarmBrightness;

var     byte AlarmHue;

var     byte AlarmSaturation;

var     bool bAlarmState; // Which state the light is in. False=NormalState, True=AlarmState

var     byte Owner;

var     pawn Controller;

//
var      bool
bAlarmEvent;

// Called at start of gameplay

simulated function BeginPlay()

{

    Disable( 'Tick' );

    if (bInitiallyOn)

    {

        bAlarmState = True;

        PlaySound (AlarmSound, , Float(SoundVolume)/128);

    }

    else

    {

        bAlarmState = False;

        PlaySound (AlarmSound, , Float(SoundVolume)*0);

    }

//  bAlarmEvent = False;

    LightPeriod = 32;

    LightPhase = 0;

    DrawType = DT_None;

    if (TeamOwner == TC_Red)

    {

        Owner = 0; //RedTeam is Owner

    }

    else if (TeamOwner == TC_Blue)

    {

        Owner = 1; //BlueTeam is Owner

    }

    else if (TeamOwner == TC_Green)

    {

        Owner = 2; //GreenTeam is Owner

    }

    else if (TeamOwner == TC_Gold)

    {

        Owner = 3; //GoldTeam is Owner

    }

    else if (TeamOwner == TC_None)

    {

        Owner = 4; //Nobody is Owner

    }

}

state() TriggerToggle

    // Trigger toggles the light from NormalState to the AlarmState and back again

{

    function Trigger( actor Other, pawn EventInstigator )

    {

    // local Trigger A;

        if ( Owner == 4)

        {

            // If the alarm is owned by nobody-->Instigator is now Owner

            bAlarmState = False;

            PlaySound (AlarmSound, , Float(SoundVolume)*0);

            if (EventInstigator.PlayerReplicationInfo.Team == TeamGamePlus(Level.Game).TEAM_Red)

            {

                Owner = 0;

            }

            if (EventInstigator.PlayerReplicationInfo.Team == TeamGamePlus(Level.Game).TEAM_Blue)

            {

                Owner = 1;

            }

            if (EventInstigator.PlayerReplicationInfo.Team == TeamGamePlus(Level.Game).TEAM_Green)

            {

                Owner = 2;

            }

            if (EventInstigator.PlayerReplicationInfo.Team == TeamGamePlus(Level.Game).TEAM_Gold)

            {

                Owner = 3;

            }

        }

        if( !bAlarmState && !TeamGamePlus(Level.Game).IsOnTeam(Other.Instigator, Owner))

        // If the alarm is off and is triggered by enemy-->sound the alarm

        {

            bAlarmState = True;

            PlaySound (AlarmSound, , Float(SoundVolume)/128);

            // if (!bAlarmEvent)

            // {

                // Execute the AlarmOnEvent (should activate a trigger)

                // ForEach AllActors ( class 'Trigger', A, AlarmOnEvent)

                // {

                // BeginEvent();

                // }

                // bAlarmEvent = True;

            // }

        }

        else if ( bAlarmState && TeamGamePlus(Level.Game).IsOnTeam(Other.Instigator, Owner))

        {

        //If the alarm is on and is triggered by owner-->turn off the alarm

            bAlarmState = False;

            PlaySound (AlarmSound, , Float(SoundVolume)*0);

            // if (bAlarmEvent)

            // {

                // Execute the AlarmOffEvent (should activate a trigger)

                // ForEach AllActors ( class 'Trigger', A, AlarmOffEvent)

                // {

                // BeginEvent();

                // }

                // bAlarmEvent = False;

            // }

        }

    }

}

function Tick( float DeltaTime)

{

    if (Owner == 0)

    {

        TeamOwnerBrightness = RedBrightness;

        TeamOwnerHue = RedHue;

        TeamOwnerSaturation = RedSaturation;

        AlarmBrightness = RedBrightness;

        AlarmHue = RedHue;

        AlarmSaturation = RedSaturation;

    }

    if (Owner == 1)

    {

        TeamOwnerBrightness = BlueBrightness;

        TeamOwnerHue = BlueHue;

        TeamOwnerSaturation = BlueSaturation;

        AlarmBrightness = BlueBrightness;

        AlarmHue = BlueHue;

        AlarmSaturation = BlueSaturation;

    }

    if (Owner == 2)

    {

        TeamOwnerBrightness = GreenBrightness;

        TeamOwnerHue = GreenHue;

        TeamOwnerSaturation = GreenSaturation;

        AlarmBrightness = GreenBrightness;

        AlarmHue = GreenHue;

        AlarmSaturation = GreenSaturation;

    }

    if (Owner == 3)

    {

        TeamOwnerBrightness = GoldBrightness;

        TeamOwnerHue = GoldHue;

        TeamOwnerSaturation = GoldSaturation;

        AlarmBrightness = GoldBrightness;

        AlarmHue = GoldHue;

        AlarmSaturation = GoldSaturation;

    }

    if (Owner == 4)

    {

        TeamOwnerBrightness = InitialBrightness;

        TeamOwnerHue = InitialHue;

        TeamOwnerSaturation = InitialSaturation;

        AlarmBrightness = InitialBrightness;

        AlarmHue = InitialHue;

        AlarmSaturation = InitialSaturation;

    }

    if (bAlarmState)

    {

        LightBrightness = AlarmBrightness;

        LightHue = AlarmHue;

        LightSaturation = AlarmSaturation;

        LightType = LT_Pulse;

    }

    if (!bAlarmState)

    {

        LightBrightness = TeamOwnerBrightness;

        LightHue = TeamOwnerHue;

        LightSaturation = TeamOwnerSaturation;

        LightType = LT_Steady;

    }

}

6. Compile the script

7. Close the script

8. In the Actor Class Browser click on View and select Show Packages

9. Select MyLevel and click on Save Pkgs.

That’s all for the scripting part. Now we can add AlarmLights to our level.

The rest:

Make a mover (that activates the AlarmLight):

The properties I used for one mover in this example map were:

Events

Event = AlarmLight1

Mover

MoverEncroachType = ME_IgnoreWhenEncroach

(not really necessary)

MoveTime = 0.500000

Object

InitialState = BumpButton

Then add an AlarmLight to your level and set it up:

The properties I used for one alarmlight in this example map were:

Events

Tag = AlarmLight1

Object

InitialState = TriggerToggle

(very important, or your alarmlight won’t work)

Under the AlarmLightProperties à AlarmLight you have to set the different colorsetting for the lights, select a sound for the alarm and select a TeamOwner (see picture), etc…

Just take a look at the picture for the “default-settings” I used.

Good luck,

IceLord (NL)

Known Problems:

The alarm-sound can disappear when you walk to far away form the alarm. I don’t know what that is caused by, so I can’t fix it…


Unreal Editor Maximum [unrealism.com/unrealedmax] - Complete Lighting Tutuorial

A COMPREHENSIVE LIGHTING TUTORIAL

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This is a medium sized tutorial that will cover all the aspects of lights. Basically all you will need to know about lighting in the beginning and intermediate stages. Lets be off then!.

LENS FLARE

Lets see the various simple steps that are involved in making a light display a flare:

1. First load a suitable texture package. For now load up GenFx.utx which has the best flares. Now from under the LensFlar subsection just choose a suitable texture.
2. Place a single light in your level where you want it to display a flare.
3. Now just go to that lights properties and set the following:

  1. First and foremost go to the lighting subsection and set bCorona to True.

  2. Now go to the display section and scroll down to Skin. Since you have already chosen the lensflare that you want to use just hit the use button. If you did not select a lensflare previously, hit the 3 dots in the skin line and when the texture browser opens choose the appropriate lensflare and then hit use.

  3. Now if you left it as it was the lensflare would be way too big. Still under the display section set bDrawScale .10 - which will reduce the size in which lensflare will be drawn. You need to set this amount depending on the situation in your level, but generally speaking .10 is a very comfortable size.

4. Ok, all you need to do now is rebuild the level to see the lensflare in it.

Lensflare makes your level look stylish and professional. But make sure you give it a light source, i.e. put it in front of a light texture to make it look more convincing.

LIGHT PROPERTIES / LIGHTING

Under a lights properties, when you expand lighting, you get to fiddle around with all lot of very cool settings I'm going to show you how to make use of all of them. All the following that is:
Light Settings user can change to get various effects.

LIGHT COLOR

I have already discussed how to make colored lighting in the UnrealEd2 Introduction. Its really simple and I don't think I need to say any more. Basically the light color is determined by the Hue and Saturations values which you can pick from the standard windows color choose. To choose the color of a light just select light color and hit the color button. This will open the windows color chooser where you can select the type of color that you want. my suggestion is that you first select a base color that from under basic colors and then move the crosshair in the light gradient and you will see the actual color being reflected in the color solid box.

LIGHT RADIUS (IMPORTANT)

The importance of this setting cannot be under emphasized. I think next to light color this is the most important setting. The light radius amount will determine how large a area that, that particular light will affect. Generally speaking a light radius of 64 is too high an area. The best way to determine the radius that a light has is to turn on radii view in all the 2d and the 3d view (to do so right click on the top of the view and from the actors menu choose radii view).

In the picture above you can see the tunnel that has been highlighted and the lights and their radius also highlighted - they have a radius of only 5 - if I had put a higher value then the light would have flooded the other areas making it difficult to determine the light source so that the others rooms would be affected for the worse. This is a case where instead of having to change the light radius of only a few lights, you will necessarily have to change the light radius of all the lights and there will be only a very few lights which you will leave with the default 64 radius.

NOTES: If you experience a case of your lens flare disappearing on you this is the setting that you will need to change. Also when lighting outdoor levels, just use a few lights with their radius set to a large amount like 175 instead of using a lot of lights which will make the level look ugly. This is the technique the pros used.

FOG

You will use the last three settings from under lighting , i.e. VolumeBrightness, VolumeFog and Volume radius. To make a light display fog is very simple.

  1. First seal the room where you want the fog to appear into a complete zone using the zone portal brush (if you don't know hot to do this you can read the Miscellaneous Zone Class tutorial here to find out).

  2. Place a normal zone info actor (from under info - don't expand zone info like you do for other subclasses). Under the zone info's properties expand zone info and set bFogZone to true.

  3. If you want to set the color of the fog you will need to set it under the zoneInfo's properties itself. Under the zone info properties just expand zone light and you will see a entry called FogColor, just hit the 3 dots at the end and the standard windows color choose will appear.

  4. If you want to set the radius of the fog or how far the fog will be seen you can set the amount under fog distance.

  5. Now we come to the lighting part of the tutorial. Just add in a single light in the room where you want the fog go to its properties and expand lighting. You will just need to set VolumeBrightness, VolumeFog and Volume radius which determine the brightness of the fog, how thick the fog is and the amount of distance it is drawn respectively.

Since fog is one of those effects that can slow down your level use it sparingly.

SPECIAL LIT

The bSpecialLit value of a light allows you to affect the surface of a specific texture without affecting the surrounding area. This means that you can have a texture surface lit with one color while the rest of the area is lit by another color.

To make use of this feature first go to the surface property (select a texture and hit F5) of the texture that you want to have specially lit (for example you can go to the surface property of a light texture to make it seem differently lit from the surrounding area. Under the textures properties in the flags tab just check special lit. Now all you need to do is place a light (or lights for that matter) nearby go to its properties and under lighting set bSpecialLit To True. You may also need to change the LightRadius for it to be displayed properly.

In the picture above the light texture is Xlight2 from the UTtech1.utx texture package (its white in color). I set its surface properties to special lit and place two lights in front who were also special lit.Notice how the room is blue in color but the light is purple.

LIGHT TYPE

Most of the light types you will find are pretty self-explanatory and I will not be able to show pictures of them without doing an animation. But use the light types sparingly as they tend to slow down levels drastically, i.e. dynamic lights (lights that basically u know ..... do stuff) slow a level down. its better to give this to a single or few lights instead of something like 50 lights - that would be asking for it :). Note to see most of these lights in action you will need to turn on Real Time Rendering by hitting the joystick button in the 3d view. Try the types one by one in your level to get a feel for it. but anyway here's a list of light types and of what they do:

  1. LT_Pulse - Heavy disco style pulse - looks like the light is just being turned on and off by itself.

  2. LT_Blink - Reminiscent of those bulbs that seem to be short circuited and about to blow at any second.

  3. LT_Flicker - Heavy blink.

  4. LT_Strobe - Disco Strobe Lights Effect.

  5. LT_Pulse - Softer pulse than the previous one.

  6. LT_TexturePaletteOnce - (See Below) Does the same as the below one only once.

  7. LT_TexturePaletteLoop - Use this in conjunction with the Special Lit technique described above. In the above example after going through the special lit stuff if I had turned the Texture Palette Loop effect on the light texture would have alternated between purple and white lights. It will give only the texture a sort of subtle pulse.

LIGHT EFFECT

Again these tend to slow a level down like anything (most of the effects though not some). Another list of the various light effects and what they do:

  1. LE_TorchWaver - Shimmery torch like effects. looks like the textures that the light effects have a fire drawn on it.

  2. LE_FireWaver - Heavier torch waver effects.

  3. LE_WateryShimmery - Looks like the texture which the light touches is reflecting water - great to use in rooms that have pools in them.

  4. LE_SearchLight - exactly like a constant search light used in prison camps.

  5. LE_SlowWave - Soft Rippling waves being drawn on the textures within the light radius.

  6. LE_FastWave - Much faster waves being drawn.

  7. LE_StaticSpot - Displays the light like a powerful, search beam focused on a single area.

  8. LE_Shock and LE_Interference - Got to be seen to be believed.

  9. LE_Disco - Huge revolving disco type lights.

  10. LE_SpotLight - Like StaticSpot.

  11. LE_NonIncidence - The difference between a LE_None (no light effect that is and LE_ NonIncidence is very subtle. The none effect casts light in a radius. Thus you can literally make out the radius stretching out. Whereas in LE_Nonincidence the light is cast uniformly without a room having a brighter center and darker corners (assuming that the light is place in the center of the room.

  12. LE_Cylinder - Whereas the static spot and spotlight cast a light directly in the face direction the LE_Cylinder effect makes it look like the light is being cast down in a straight cylinder from the light source. The light radius must be very small like 4 or 5 or depending on your level to achieve this effect.

    Note: The same effect can be achieved with static spot.

  13. LE_Rotor - Like the blades of a heli rotating in the room.


Lighting

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

Tutorial:

I decided to write this tutorial in regards of the awful lighting I see in most maps, and because lighting is my favourite part of map making.
The problem is that most people don't even think about their lighting, in the following I try to give some hints. It's not the ultimative lighting,
it is what I like. This tutorial requires that you already know how to use your tool (UnrealEd), I won't explain that.

1. Basic Lighting
As example I use this room (unlit in this pic). You better open one map you are working on at the moment and try out the things I'm gonna try to explain.

Newbies use to fill their maps with default light actors (hold down 'L' and click around in the map) which mostly looks like this.

And please use light sources. Nothing looks worse than a map without light sources/lamps.
Open the light actor properties. The basic options you need to know are marked red.

A saturation of 255 means that the light color is white, what I NEVER do.
A radius of 64 is mostly way too big, and the default brightness of 64 is not bright enough.

Good lighting is about good contrasts -> warm colours -cold colours; sharp shadows-blurry shadows....and so on. You should have a healthy mix of all.
Now let's add lights to an empty map
Place them only next to a lamp. Let's call it LOCAL LIGHT!

I've given the lamp a warm colour (25=brown). Don't use too low saturations (0-100) or it will be more colourful than a gayparade, but keep them under 210, or they will be white again.
Brightness shouln't be higher than 200 or you will get a greening effect, in the unreal engine lights use to turn green when they are too bright.
Now we have a warm light with a small radius and a high brightness. A good contrast is a cold light with a high radius and a lower brightness.
It's the so called GLOBAL LIGHT!

The next problem: the blue light is supposed to be given off from the big lamps on the ceiling, but they don't look like giving off light because the brightness is too low.
So you place another light next to the lamps.

They have to have the same colour settings like the other light, but a higher brightness and a very low radius, that they only lit the lamps, nothing else.
Now compare that to the first lit pic.......much better I guess. Don't be affraid that it is too dark, in the editor it's always too dark, but ingame it's ok.
In the next room you can use a big warm light and small cold lights, otherwise it will look the same overal. Go gr4zy with that stuff.
Don't use colors like green or purple, their destination is to look gay, and so will your map. =)


Red Lights

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

One cool thing are small red lamps. Something most people do wrong in my opinion is that they place red lamps in already lit parts of the map
which doesn't look good IMO. They tend to look purple and just lose the cool effect.
Do not do it like in this pic!

Do it like here.

Give it a small radius (like 8)
Brightness: 200
Saturation: 0
Hue:0

Don't go crazy with them, use them very carefully!


Cylinder Lights

Cylinder Lights & Lightboxes

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

Cylinderlight is a 'lighteffect' and it's mostly used in a very awful way. DM-Deck16 and DM-Grinder show perfectly how NOT to use them.
Instead of 'cylinderlight' you can also choose 'non-incidence', it's almost the same. Find out the small difference.

It's mostly used that way.

It's just a circle and not smooth at all. I think it's ugly.

You see, its smoother now. Let me explain. Light 1 is the cylinderlight, don't use a too big brightness.
Light 2 is a normal light (not cylinder) with a low brightness. It causes the smooth fade and it gives off some light to the environment, without it the wall next to it
would be pitch black, which would suck.
Light 3 is the same like in the first example. Without it the lampbrush would not look like giving off light.

Now add a lightbox actor from the deco class. Find the right scaling, that it fits the size of your lamp and align it.

Use it only for lamps where the relation of the sides is 1:1.
I get sick when I see it used on 2:1 lamps. That just cannot work.

Most mappers ignore the 'ScaleGlow' option.
I always turn it down to 0.5 or so, then the lightbox looks way better IMO.
It's not a big difference in this pic 'cause of the dark lighting, but usually it looks much better.

The alignment is an important thing. Don't do it like in these pix

Is that laziness or why does it happen so often?
I hope I don't need to explain why they are wrong placed.

A lightbox is NOT some kind of plastic tube that you put on lamps it's a "light beam" cast by the light itself.


Just Something...

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

Something you should never do. One kind of lamps does NOT give off different colors.
This one is wrong.

You see, it's the same type of lamp, but its a different color.

This one is right.


Lens Flares

Lens Flares/Coronas

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

Choice:

First let me clear up the typical novice mistakes in terms of lensflares.
Don't use flares that look cool on pics, they will make you vomit once you play the map and watch them.
And don't use colored ones. White ones only, because of the hue and saturation values of the light actor
it will have the right color.

That's all the lensflares from GenFX.utx.

RED - Don't use them under any circumstances.
BLUE - Use it only for candles.
GREEN - They can be used EVERYWHERE. Especially flare '3'. It's the best imo.
YELLOW - They are ok, but actually a worse version of flare '3'.

I remember, the first flare I used was '2', it looks good on that pic, but in game........blaaargh.
Now decide for yourself, which one do you like more? Pic1 (flare '3') or pic2 (flare '2'). If your answer was 'pic2' imagine some cruel insults here (Hint: right answer is 'pic1').
pic1

pic2

Settings:

Drawscale is the size. 0.1-0.2 is ok there. Default is 1 and waaaaay too big.
Skin, enter the flare texture here (3).
Brightness: 0, because the flare itself shouldn't give off light.
Hue & Saturation: same here like for the light that gives off the light that is supposed to come from the lamp. So the flare gets the right color.
Corona: true! NOT LENS FLARE! I have no idea what lens flare is for, but you don't need it!
Radius: 255 means that you always see it, from every range. But that would look stupid, 48-64 is ok.

Alignment:

The alignment is often very awful.
The flare appears in the middle of the light actor. This is somewhere in that red circle.

The brown glowing/selected brush is the lamp from pic 2 and 3 of that tutorial. Now align the light actor with the flare settings in the middle below the lamp.
Don't place it inside a brush. It won't be visible any more (except it's a non-solid brush).

Alignment in Fire:

Seems to be a hard thing too. No idea why that happens so often, but I see it all the time.
Here one of 1000 wrong examples. (No, I did not manipulate it!)

Place it in the center of the heat, at the brightest point, not on the top or somewhere else!
You may say: 'but in real life I see a corona on the top'......well, look at this pic, it looks so damn retarded, and it doesn't work like in real life.
Just place it where I told you and it looks perfect.


BrightCorners

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

If a texture stays black although there is a lightsource next to it, activate the 'BrightCorners' box in the Surface Properties.
Rebuild the lighting and the problem should be gone.

Same thing here, surface 2 is darker than surface 1.
Make 2 'brightcorners'. If that doesn't help do the same with 1.

2. Lamp not bright enough

Avoid stuff like that. The lamp must be as bright as the corona.

-Make the lamp texture 'brightcorners'
-Place a light close to the lamp, very bright (not more than 190) small radius (~3), maybe use it as cylinder light...

3. "Mysha Greenings"

I've already mentioned it in the main tutorial (1). Lights turn green when they are too bright.
Here a pic of one of the most awful greenings I've ever seen! That's an editor shot (darker than in game), in game it's much worse!!

All lights have a brightness of 199. They add to each other and that makes a brightness of ~400
and it starts getting green from 220 on.

I've lowered the brightness and it looks already much healthier. Ok, the orange-yellow color still sucks
but I just wanted to show the greening stuff.


Outdoor Lighting

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/


deCyber Build Section

Lighting

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Downloadable files : Lighting.UNR

Contents

1) Standard Lighting
2) Surface light
3) Coronas
4) Trigger Lights
5) Fog
6) Ambient Lighting
7) Tips

Introduction

Again, as with any of my other tutorials, I don't claim to be an expert. If you liked the look of my levels, one of the things that contributes a great deal to this is the lighting. I don't understand all the lighting functions, in fact a lot of it is still a mystery to me, but I can share what I've found out.

To give great atmosphere in a game, the lighting should be as realistic as possible. Not too dark, not too bright and not too harsh.

Lighting should nearly always have a source; it doesn't come from thin air but needs a lamp, torch or some other device that radiates light.

Here's how to create lighting:

Standard Lighting:

1) Create a room as normal. Make it large, so that you can get a feel for what your lights will do.

2) Its really simple to add a light to a room. Just right click anywhere in the 3D view to bring the menu up and you'll see an option that says "add light here". Click that.

3) You should then see a small torch appear on one of your walls. Maneuver this to the center of your room, rebuild and save the map (Call it "lights")

4) The small torch won't appear when you play the level, all you will see is a patch of light on nearby surfaces. If you don't see anything its probably because your room is a little on the large size. (You can change how far the light reaches by changing its properties).

5) Click on your light and press F4. A properties box will appear. There are only a few of these properties that I will cover in this tutorial. "Display", "LightColor", and "Lighting".
(I will cover other properties when we look at "triggerable lights")

6) First click on the property called "Lighting" and use the information below to set up your light as you would like it. Some of these fields are a mystery to me, so I will only discuss the fields that I know about:

bCorona and bLensFlare are used to give that realistic feel to bright light sources. I will go into specific detail about this later.

LightEffect and LightType both give your light a special effect of some kind. For example, if you had created a small torch with flames coming out of it, you would want your light to have a faint flickery effect. To do this you would choose the "Lighteffect" dropdown menu option called "LE_torch waver".
Experiment with these to try out different effects, but remember not to use to many special effects as this tends to eat up a lot of processor power.

LightRadius. By default this is set to 64, but it will go up to 255. The larger the number, the greater area your light will spread.

VolumeBrightness, VolumeFog and VolumeRadius are all specific to creating foggy light which I will cover later

7) This is the nicest bit I think. :) This is where you give some color to your lights.

Again, bring up the property box for your light and click on "LightColor". You should see 3 more fields appear called "brightness", "hue" and "saturation"

Brightness is by default set at 64 but can go up to 255. Obviously, the higher the number you choose, the brighter your light will be.

Hue and Saturation both control the actual color spectrum. By default the hue is set to 0 and the saturation is set to 255. The higher the number for saturation, the whiter the light will be. If saturation is set to 0 then the full depth of the hue can be seen. Try different combinations to see what colors you get. Here are a few:

Hue =0, Saturation =0: Harsh, bright red, good for "red alert" signs
Hue =80, Saturation =0: Harsh, bright green,
Hue =180, Saturation = 0: Deep blue light
Hue = 36, Saturation = 60: Warm, amber firelight.

Light effects on surfaces:

There will be times when you want a surface to stand out without having to have an actual light to create that effect. To do this, click on the surface of the brush that you want to stand out. (This could be a transparent flame for example).

Now press F5 and you'll see the properties come up for that textured surface. Make sure it’s on the tab called "effects". There are lots of useful attributes there, but the one we're interested in is "unlit". Click on that so a tick appears. This means that this surface is no longer effected by any light actors. The whole of the surface just glows in the dark.

Another useful attribute here is "bright corners". There will be times when you've made a really small indented brush in your wall or something similar. No matter how bright you do your lights, or however big a radius you use, you just can't get the area inside this brush to light up. If you tick "bright corners" it will react to the lights you put near it.

Coronas:

These are great when you want a really impressive bright light, but remember not to have too many of these as it could slow things down a little bit.

Set a light actor up in the usual way and then bring up its properties by pressing F4. Click on "lighting" and set "bCorona" to true.

Next you need to give the light a "skin". In the properties box, click on "Display" and another set of properties will appear. Amongst those is a field called "skin" which should be blank. This is where you tell Unreal that the light actor will be visible in the game, and what it looks like.

Now bring up the "texture browser". At the bottom of this toolbar press "load" and with the browser pick "SpaceFX". Look through this texture file and you will find a small collection of different coloured stars. Choose
one you like for your light by clicking on it. Then, in the field called "skin" in your light's properties click on "use"
(this button will appear when you click on the field).

Rebuild, save and play and you should see a nice corona where your light is sourced from. If you can't see it, it may simply be the positioning of the light. Fiddle and play with its position, until you can see it properly.

Triggerable Lights

You can add triggerable lights to your world and adjust their properties in exactly the same way, but the advantage here is that you can turn these on and off.

Click on "classes" in your right hand tool bar, then click on "lighting" and a whole list of different types of light will appear. Choose "TriggerLight" (there are 2, but either will do).

Right click somewhere in your map in the 3D view and choose "add TriggerLight". You will see a light appear that looks just the same as the ordinary lights. Adjust it and get it looking exactly as you want by changing its properties (F4).

Now in the property box click on the property called "Object". You will see more properties, you need to click the one called "initial state". A drop down menu will appear with the following options: "Trigger pound", "Trigger control", "Trigger toggle", "Trigger Turns Off", "Trigger turns on"

Trigger Pound, I believe will keep the light on as long as the player stays near the trigger.

Trigger Control is triggered as long as a normal trigger is in use.

Trigger Toggle is applied when you want to be able to turn the light on and off
whenever you like. each time the light is triggered it will change from on to
off or vice versa.

Trigger Turns Off is exactly that, and Trigger turns on also speaks for itself.

Once you've decided which one of these to use, click on "Events" and give your light a Tag name. When you want this light to be triggered, just put this tag name in the event property of the thing that triggers it.

Now, also in the Trigger Light's properties you'll find a property called "Trigger Light", click on that and you'll find some more useful fields. You can make your light fade in or out when its triggered by typing in a number (seconds) in the field called "Change Time". You'll need to set the trigger to be either on or off before its actually triggered. If you want it to be turned off when its triggered set this field to "true", and obviously set it to "false" if you want it be off before being triggered. "Remain on time" is exactly what it says.

Foggy Light

Add a light to your world in the normal way, but this time you need to add an extra item. Click on "Classes" from your right hand toolbar and find the section called "Info". In that section you will find another section called "ZoneInfo".

See the tutorial on zones for more information on these.

There are different types of zones, but just choose this one and add it to your map.

Once you’ve added it to you map, it should appear as a small cube with a question mark in it. Click on it and bring up its property box (F4). Under the property called "Zone Info" there should be a field that says "fog zone". Click on this and select "true"

Now you need to add some information to your light to tell it about the fog. Bring up the property box for your light and choose the "lighting" option. You will need to adjust these three settings to create a fig effect with your light:

"VolumeBrightness", "VolumeFog" and "VolumeRadius.

VolumeBrightness and VolumeRadius work the same way as the normal lighting attributes, and VolumeFog effects the density of your fog.Try experimenting (also check out the sample map) and you’ll soon get the hang of it.

Ambient Lighting

As well as using individual lights to light an area you can speed up your maps performance by giving zones (or the whole map) ambient lighting. For the whole level, bring up the level properties (right click in UnrealEd2) from the top menu. Right at the bottom of the properties is a section called "ZoneLight". Open that out and adjust the ambient brightness, hue and saturation to your taste. The draw back is that the lighting is everywhere so the textures can look a bit flat without the usual lighting. Its best to use normal lights in conjunction with this method and keep the ambient brightness to a maximum of 12.

Tips:

1) Try and avoid using fancy lighting effects and foggy areas in large outside places, it will slow things down quite a bit.

2) Keep the radius of your lights small. With a large radius the light hits more surfaces. The more surfaces your lights hit the more calculations your processor has to make and the slower your game gets.

3) Use the "group" command to change multiple lights. When you set up the properties of your lights open up the "Object" section and give the field "group" any name you like. All the lights that you are using for ambient lights can be given this same name. When you want to adjust all of them at the same time again, simply right click on one of them and choose "select all". All of the lights with that group name will then be selected. You can do this with anything, not just lights.

4) If you open up the properties of anything you add to your map, whether it's a brush or an actor, you'll notice it has lighting properties too. These can be used in the same way but usually they aren't "activated". Make sure that the "Light Type" field under the "Lighting" section is set to "LT_Steady" and then adjust all the usual attributes and a light source will come from the focal point of your object. This is especially useful with moving brushes for obvious reasons (moving lights duh!)


Movers

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    Forward:

    Since doors and all the other stuff that moves are really the same thing, I will post them as one tutorial.

    Abstract:

    I have been asked to post a tutorial about doors, I have also been asked about other movers. They really are the same thing, so I will be posting them as one tutorial.

    Assumptions:

    I am assuming that you know how to use UnrealED with a fair amount of practice. I don't expect you to be perfect - otherwise you wouldn't be reading this tutorial :)

    Tutorial:

    Introduction:

    I will be starting with simple mover (A door I think) and going on to more and more complex things. I would expect that you are quite familiar with UnrealED to complete this tutorial entirely, but if you just want to know how to make a door move; then this will also help you out. Feel free to stop when I have reached the level that you want to go to...

    The starting point:

    You can do this in a level that you have already created, but I would ask that you spend the time and just start a new one for this tutorial. This way, you will be able to follow my instructions easier - and you will repeat the doors when you go back to your own level, further imprinting it in your mind.

    The room:

    Let's make a room that is fairly large. Create a cube 256x1024x1024 and make it look like a room (Textures, Playerstart and lights etc.). When the room is complete, make a cube 256x1024x32 and place it in the middle of the room to make two rectangular rooms. This will form the basis of the tutorial. Now in the middle of the wall (At floor level) create a cube 128x128x32 and "subtract" it from the wall. This will be the doorway.

    A simple swinging door:

    To make the door move, we have to create a mover; so here are the steps. Firstly create the door with a cube (128x128x16). Make sure however when you are creating the door, that you create it in the MIDDLE of one of the rooms ans in the air (as opposed to in the doorway). When you have made the door, make sure that you are happy with the textures, the texture alignment, scale and the like as there will be no way to change them later.

    When you are happy with the way the door looks, make a brush that is bigger then the door (150x150x100 for example) and place it around the door (make sure that the new brush completely covers the door) and press the "intersect" button.

    If you are not sure at this time, check out my buttons tutorial and come back. When you have intersected the door, move your new brush to the doorway, and place it where you want it to go. Now click the "add mover" button. Move the red brush away from the door (it will only get in the way) and select the mover (Left Click). Once it is highlighted, right click on it (making sure it is the only thing selected) and select "Mover Keyframe --> Key 1". Now rotate the door to an open angle and make sure the hinges are still close to the wall, right click and select "Mover Keyframe --> Key 0" At this point your door should move back to the doorway. You should be ready to try it out now. Rebuild the level and have a go...

    Sliding door:

    You will at some time want to have a sliding door, so let's get into it... To build a sliding door is actually easier in a way, then a swinging one. All you have to do is create the door as detailed above (ie NOT in the doorway) and when you are happy with it, intersect it with a larger cube. When you have your new brush, move the brush to where you want the door to slide into (Not in the doorway, but actually in the wall (at this point you probably should lower the grid size. If you haven't done this allready; simply Right Click in one of the 2D views and select "gridsize" and then maybe one or two). Now make sure that the new brush "touches" the wall that the door "attached" to. When placed, subtract the brush. You should now have a hole in to wall just to the side of the doorway. You can change the textures if you like, but if you do it properly, then these textures will never be seen anyway :) Now move the brush to where you want the door (This should be just to the side of where you cut the hole just earlier) and click the "add mover" button. Get the red brush out of the way, then select the mover itself (It has a purple outline) and right click it. Select mover keyframe--> key 1. Now move the door into the hole in the wall and right click it again. This time select mover keyframe--> key 0. Your door should move itself back to where you originally placed it. That is all there is to it. Rebuild the level and try it.

    Automatic doors:

    You should notice that the door work quite well, but you actually have to run and "bump" into them to open them. It would be much better if they just opened when you ran "near" them wouldn't it? The first thing you will have to do is add a trigger. To do this, go to the "classes" menu (it's right next to "browse" on the right of the screen) and select "triggers" from the bottom of the list. Expand the section and select "trigger". Place the trigger in the map (Do this by right clicking in the 3D view and select "add trigger here". When you have the trigger where you want it (it should probably be just in front of the door), and select it.

    Now right click and select advanced properties. In the advanced properties, choose "events" and change "event" from none to "firstdoor". When you have done that, click the door again (The mover actually) and right click it. Select "advanced properties" and go to "events". Change the "tag" from none to "firstdoor". Now this is important, go to the "object" section and you should see a entry named "initial state" this is set to "bumpopentimed" by default. Change it to "triggeropentimed". This is important because even if you have a trigger made for the door (or any mover for that matter) it won't be effected by the trigger until you let it be "triggered" (sorry for the pun hehehe :). At this point, you could rebuild and try it out, but before you do that I will make you do one more thing. Left Click on the trigger (to select it) and press CTRL W. This will create another trigger exactly the same as the one that is there (you can duplicate almost anything using this) and place it on the other side of the door. If you didn't do this, you would have a door that only opens from one side - which is fine if you want to "trap" a player in a particular area, but we don't want to do that in the tutorial... Rebuild and have a go.

    Doors with sound:

    All this should be pretty cool huh? But our doors need to make all those cool sounds that doors make, right? (If you disagree - then the end of the world will occur and all my work will be in vain. OOPS sorry, I forgot where I was :) Where was I, Yes doors that make sounds. Select the door and bring up the advanced properties. Bring up the "mover sounds" and select "ClosedSound". You should see three little dots in the same cell. Click them and this will bring up the "sounds" menu on the right hand side of the UnrealED window. Click the "load" button below the main sounds toolbar. If you like a ancient or fantasy setting choose "DoorsAnc" or if you like a more futuristic feeling, choose "DoorsMod". You can play a sound before you set it to the mover by clicking the sound in the "sounds toolbar" and pressing "play" at the bottom of the toolbar. When you have found a sound that suits your needs, press the "Use" button which is located next to the three little dots (in the advanced Properties window) and this sound will be set to the door when it closes. Please Repeat the sound for the "opening Sound" and we should be able to have a go and play the level. Rebuild it and let's have some fun.

    Additional Notes:

    By this time, you should have noticed that the doors we made are simply made from "movers" not a special piece called "moving door" or something like that. Doors are in no way different to elevators or anything else that moves. By now you should be able t replace the stairs in your level with movers and make the level much more animated. If you would like to know something n particular about doors or how to do something with movers, then contact me at the above address. I think that doors are quite important in a level, so I will go into more (yes that's right, MORE!) depth with doors in a later tutorial, but I think that this will keep most people happy for the time being...


Provided by

 Mover Sounds

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

Forward:

I had a mate just ask about what on earth all the sounds are for a mover, so here is the listing.

Abstract:

I will explain what each of the sound properties for a mover are used for.

Assumptions:

I am assuming that you have already made the mover, and are just playing with the sounds to make it more realistic. For the ease of explanation, I will pretend that this is a door and thus explain what the sound would be like.

Tutorial:

Opening Sound:

This is the sound that your door will make when it starts "opening". Ie I would place a nice creaking sound, so that the door will sound like the hinges need a little oil. Don't can use the "Looped" sound for this section, as as it can cause your sounds not to work properly.

Opened Sound:

This sound is what the player will hear when the door has finished "Opening". If you have the door set to open wide until it hits the wall, then I would use a booming sound for it. This should NOT be a looped sound because it would keep playing until your door starts to swing shut.

Ambient Mover Sound:

This sound will be emitted from the mover while it is in motion. If you have a futuristic door, this might be a small hum from the motors whirling while it opens/closes. You should make sure that this sound is quiet and not overwhelming, as it will always heard in the visinity of the mover whenever it is moving.

Closing Sound:

This sound is made when the door is closing. It will be heard when the door starts to close, and ind play over the top of any "Ambient Mover Sound" that may be selected.

Closed Sound:

This is the sound that is made when the door finally closes after being open. This is normally a good time to put in that really evil, booming thud that makes every bone shiver in a players body... :) I like to add in something as ominous as I can for that simply effect.

Ambeint Sound:

You can select this from the "Sounds" menu, as compared to the "Mover Sounds" that the rest are kept in. This will allow you to have a sound playing in the visinity of the mover ALL THE TIME. You should use this carefully, as it chews up system resources, and you may not want it to be playing after the mover has done something...


Movers 2

    By: Verxion (jc83151@goodnet.com)

    Third installment coming up. I feel like I am getting pretty good at making these tutorials now. One small clarification I thought I would make is that on IRC, I go by the nick Verxion. So if you see me on UnrealED, take a sec to say hi. :-)

    ABSTRACT:

    Well, I have seen several tutorials around concerning movers, but I was asked to do one on movers, so I shall. :-) Rather than take the "easy" was out and simply do one step of motion with our mover, I am going to go over some of the more intricate things movers can do. I will start simple though, rather than overwhelm you with one of the more complicated ones to begin with.

    ASSUMPTIONS:

    You know how to make a room, put a playerstart in it, how to move and shape your brush, and deal with textures.

    TUTORIAL:

    First off, make a room at least 512x512x512. Next, right click on your brush, and choose "Reset -> Reset all positioning" (Your brush should be 256x256x256 now. If not, please make it so :-). Put this brush in mid air. Choose a texture, and "add" it into the room.

    caption: here, you see the textured block in mid-air

    Now, right click on your brush. Choose "reset -> reset scaling" This step was very important. Let me explain why. If you did not reset the scaling at this point, and your brush had been scaled before hand, it would not allow your mover to work right. Instead, it would allow you to walk THROUGH it instead of being solid. So if, after making your mover, you find that you can walk through it and it doesn't work right, this was probably the step you messed up on. :-)

    Right click on the "Build a Cube" button on the control panel (the cube to the right of the control panel). Choose "Cube Properties". In here, change the height width and breadth to values of 300. This should cause your brush to be slightly larger than the cube you made.

    Next, move your brush so that it surrounds the block. Once you are certain the brush fully surrounds it intersect the block. (To do this, you can either click on the intersect button in the toolbar, or go to the "brush" menu, and choose "intersect). Now, right click on the brush, and choose "Copy polygons -> To brush". This will copy the textures and the shape of your block (soon to be a mover) into memory.

    The step I am about to give you can happen anytime that you choose. If you are confident that you did the previous steps right, you can do this step now. If you think something may have gone wrong or are unsure, you can wait to do this step until after you try your mover. This step involves the block you just copied. It is hanging in the middle of your room. You need to delete this at some point. :-) You can either do it now, or after you know your mover works.

    Next, place your brush onto the floor. Once you have the brush positioned where you want it, click on the "add mover" icon in the toolbar. (The box with swirling mist coming out of it.) Move your original brush out of the way, and you should see the purple "brush" that is called the "mover".

    caption: Here, in purple, you can see the mover at keyframe zero.

    Next, we need to tell UnrealED where the mover wants to move. Right click on the purple mover, and choose "Mover keyframe -> Key 1". Now, in the perspective view, while the mover is selected, hold both mouse buttons down and translate the mover vertically. I recommend doing this in the perspective view because you can see clearly where you are placing the mover, and you can easily restrict the motion of the mover to the Z axis only.

    caption: Here, in purple, you can see the mover at keyframe one.

    We are almost ready to try our mover out. Just right click on the mover again, and put the keyframe back to zero (mover keyframe -> Key 0). This sets the initial position of the mover for when the map starts. Now, you can F8, rebuild map, and ctrl-p it to try your new mover out!

    If you walk up to your mover, you should automatically trigger it to move. Watch it as it moves up into the air. :-)

    Next, lets assume you want some sound effects associated with your mover. Choose "SoundFX" on the browse side, and load "activates.utx". Now, right click on your mover, and choose "Mover Properties". In this dialog, choose "MoverSounds".

    caption: Here you can see the mover properties dialog with the sounds already selected.

    Now, in the dialog, click on the "OpeningSound". On the Browse menu, choose "SoundFX", and "Activates" in the dropdown below it. As an example sound, choose "sclick2". Now, you should be able to click on "use" next to "OpeningSound". If you don't see the "use" button, click on "OpeningSound" in the Mover Properties dialog, then you should see the "use" button.

    You can do the same thing to set "ClosedSound" to "sclick3" and "MoveAmbientSound" to "phumb6bL". Now do your F8, rebuild, and ctrl-p. You should hear sounds now when the cube moves.

    Ok, the last thing I am going to cover in this mover tutorial is the fact that you can have more than 2 keyframes. All of the tutorials on movers that I have seen have only 2 keyframes. Is it hard to do more than 2 keyframes? No. Could you probably figure it out on your own? I think so. But just to be thorough, here we go.

    Right click on your mover, and choose "Mover Keyframe -> Key 2". You shouldn't notice any perceptible change. Slide your mover over on the floor to the right of its current location. Next, you need to change the default number of keys from 2 to 3. You do this in "Mover Properties". Right click on your mover to open the properties. Choose "Mover" and then choose "NumKeys" and type in a value of "3". I think it is the fact that you have to change the "NumKeys" value that keeps most people from doing more than 2 keyframes. Ok, do an F8, rebuild, and ctrl-p to try your mover out!

    caption: Here is the mover at keyframe 2 position, the red brush is at keyframe 0 (base).

    You will probably think your mover only has sound while moving at the beginning. The sound is an ambient sound that occurs while it is moving, and the sound doesn't have a large radius. If you walk over to where the mover is headed, and wait for it to move BACK to its original spot, you will hear the ambient sound because you are close enough to it to hear it.

    Just keep in mind, you need to set "NumKeys" to the number of keyframes you want to use. I hope you get a LOT of use out of the mover, it is really an awesome tool in the world of Unreal. For some truly advanced use of Movers, look for my upcoming tutorial entitled "Advanced Doors".

    Good Luck


Moving Brushes

Strange Movers

by: Andrew
mjolnir@t-online.de

Using Movers as things which don't appear to be movers etc.

First I want to say that this tutorial is not going to have any pictures included. Also you'll have to know how to build things yourself, adding and subtracting, and if you don't I suggest reading a beginners tutorial. I wrote this from memory so if any of the names are wrong then sorry. Right:

What I'll talk about first is exploding crates. Unreal Classes supply breakable crates and exploding Tarydium Barrels. But it's possible to build your own exploding crates without scripting, which I have completely avoided so far.

First, build a crate in a box outside your level (a solid crate, not one from classes), suitably decorated with warning stripes or something. Intersect in and put it on the floor in your level. If you like you can change the floor texture underneath it, make it scorched or something. You may have to create your own scorched texture, because there aren't very many (if any) in unreal. The idea is no one should be able to see the scorch marks until the crate has gone.

Now set up the mover so it's damage triggered, put it on TriggerOnceOnly, set Object to TriggerOpen- Timed, and set MoveTime to 0. Put Keyframe 1 to underground (or anywhere outside the level), and make sure it's set to IgnoreWhenEncroached. Hope you know how to do all that and where to find them. To make it damage triggered simply make DamageTriggered be True and set DamageThreshhold to 5 or so.

Set the Event to anything you like. If I have to be specific make it Banging. Now add some Explosion Chains (they're in effects) to the area inside the crate. I built five of them and set them on size 4, that makes a pretty big explosion but it might not run so well on slower computers. Set their tag to Banging or whatever Event you gave your Mover, and set the delay time of the explosions to 0.01 . Now try out your level, see if the crate explodes when shot. If not then you'll just have to check that everything's set up right, perhaps I have left something out here.

Now, if all is well then we want to add some exploded bits to fly around when the crate explodes. Put an Exploding Wall inside the crate (under Effects) and set it's Event to Banging or whatever you called your Mover's Event. Hit the + Collision and set it's ProjectileTarget to False. This means that it can't be activated by being shot, and sort of "steal" the shot which should have hit the crate. Make sure OnlyTriggerable is set to True.

Set the WallTexture under + ExplodingWall to whichever texture you use most on your crate, and experiment to see how many wall pieces at which size it needs to look realistic.

Incidentally this is more or less how you build breaking glass but there are other tutorials for that. Now, if you want two exploding crates side by side and want them to set each other off, then here's how you do it. You have one crate with an Event called Banging. Possibly. Set it's Tag to, say, Banged and build another crate just like it with an Event of BangingB and a Tag of BangedB. Now add two Dispatchers (under Triggers, in Classes) anywhere on your level, although nearby would be better to avoid confusion. Set the first one's tag to Banging and then open + Dispatcher, open + OutEvents and type BangedB in the first slot. In the first slot in + OutDelays enter the amount of time in seconds between the first crate exploding and the second crate exploding, any time from 0.2 to 0.05 would be good. In the second Dispatcher set the Tag to BangingB, and the first OutEvent to Banged, but keep the first OutDelay the same. This means that when one crate dies, the other crate die almost immediately. The second crate to explode will trigger the first again but that's alright because they're both TriggerOnceOnly. Test your level. Hopefully it's cool.

Right, if you want you can make three crates in a row, and have the middle crate triggering the other two, and each of the outer ones triggering the middle. If you shoot the one on the right, then the it explodes, then the middle one and then the one on the left, all in quick succession. If you shoot the middle one, then it will explode first followed by the left and right ones. From this you can build an entire group of crates and make them all explode in sequence, if you have got far too much time on your hands. This will probably take up[ a lot of memory.

Hopefully you realize that it could be anything you want, not just crates. Entire rooms filled with dynamite, or whatever you want. If you don't want them to explode in sequence, instead all at once, you can make them all as the same mover. If this is inconvenient for whatever reason, then do without the Dispatchers and have the Event of one Mover as the Tag of another. You can also make them not triggered by being shot but by, well, pushing a plunger. Almost nothing is impossible...

Non-exploding breakable crates

Well, basically the same as exploding crates except that you don't include the chain explosions and don't make them trigger each other. But now it gets harder, when we start making them break in separate pieces, i.e. building separate movers for just one crate. The easiest pieces to divide a crate into is of course each of the sides, top, bottom, front, back, left and right. This means more ExplodingWalls and more work. Now our problem is that the top can remain hanging in mid air when the sides have all been shot, and the nicest way to cure this is as follows:

Let's say the sides of the crate have the following events: CratewallA, CratewallB, CratewallC and CratewallD. Now add 4 Dispatchers, each one with the tag of one of the walls,OutDelays left at 0, and all with CrateRoofCount. Now add a Counter (under Triggers) and delete it's message, set it's Tag to CrateRoofCount, make it count up to three, and make it's Event CrateRoof, this being the Tag for the top of the crate.

This means that as soon as three of the sides of the crate are broken, the top will break too. This way does involve a lot of work, though, so you might want to just have the top of the crate attached to one of the walls, so when it goes, the roof does too.

You can divide your crates (or whatever) up in whichever way you like, along seams or edges, or in random jaggedy patterns. Hope you understand what I'm saying.

One more special thing: You can have these crates next to exploding crates in your warehouse or whatever your building. Simply make the exploding crate trigger all the pieces of the non-exploding crate, possibly with a dispatcher delay it a bit, but it will probably look just as good without one.

Next: Collectables which aren't really collectables

This is an idea which I've seen used in levels downloaded off the Internet. Build a mover in the shape of a key, and put it on a table. (Or whatever.) Set it's Event to Unlock, make it BumpOpenTimed, set it to TriggerOnceOnly, put keyframe one inside a wall, make it IgnoreWhenEncroached, and set it's MoveTime to 0. Give it a collectable sort of noise as it's OpeningSound, and add a SpecialEvent with the Tag of Unlock and set to DisplayMessage (under Object). As it's message, type something like: Picked up the Silver Key. So now it looks and sounds just like a collectable. Now, in front of a door somewhere in the level, add a Trigger. Set it's Object to OtherTriggerTurnsOn, set it's Tag to Unlock and it's Event to the door's tag. So, the idea is, you go to the door but can't open it, then find a key, then come back and the door opens. Just like switches really but you're given the illusion that you're carrying the key. This could also be the gem of power which you stick in to it's holder and then everything explodes, or a magnetic card to open a security door. Whatever you want, as I'm sure I've said before.

Finally: Complex movers

It is possible to build a lift with a door. Make a button just outside the lift. The lift mover will have to be built in separate pices, the lift itself and it's door as two different movers. The button has the event StartLift. Then add a Dispatcher, with the Tag of Startlift. In OutDelays, in the first and second slot enter a 1. In OutEvents, type in LiftDoor in the first slot and Lift as the second.

Now in your lift properties, enter the Tag as Lift, and set the object to TriggerToggle.

Put keyframe 1 wherever you want the lift to go. For the door, set the Tag to LiftDoor, set Object to TriggerToggle, and then open + Mover. Set NumKeys to 4, and set Movetime to 3.

Now, keyframe 0 has to be the door open next to the lift's keyframe 0. Keyframe 1 is the door closed there, keyframe 2 is the door closed at the lift's keyframe 1, and keyfame 3 is the door open there. Got that? You'll need a button at both places the lift goes.

To add complication, you can have double doors, lift doors and outer doors if you understand what I mean, or even a fast train which goes on a relatively straight line between two stops with opening and closing doors. If you're smart enough you can put a button inside a lift, and make it move with it, but you'll have to have a Trigger to trigger the button, rather than the button being BumpOpenTimed. This is due to the fact that the button would only trigger the lift when it had already got to where the lift is going.

Problems: This is quite complicated, and also if you stand inside the doors as they close they will bounce back and the whole lift will get out of sync. This means you have to set it all on CrushWhenEncroach, but then the lift will be a dangerous place.

Well that's it. I hope you understood most of it because I was hoping you already knew how to use things like Dispatchers and Counters.


Moving Decorations

Moving Decorations (Spaceships, Cars, etc.)

by: Eric Poggel
E_Poggel@Hotmail.com

If you"ve ever played one of my maps, then you probably already know what this tutorial is about. For those of you who haven"t, this will show you how to make an effect similar to the cars and spaceships in the UT cityintro map. In this tutorial, however, our ship will fly around a large circular path. Only part of the circumference of that circle will pass over our map. This will make it so the ship will fly over every thirty seconds to about every five minutes, depending on the ship speed and radius of the circle.

The first step is to decide where you want your ship to fly. Outdoor areas are good, obviously. Create a large subtracted cube above your level where the sky is. Create a skybox and set the edges of your cube to "Fake Backdrop." Make sure the lower edges of the cube can"t be seen, or else you ship will suddenly disappear whenever it reaches the edge of the cube. We want it to be concealed from view before it disappears into the area outside the level.

Now, set your red builder brush to "Cube" and move it someplace outside your level. In Ued 2.0, right click on the mover button and select "Attach Mover." An attach mover is just like a regular mover, except that you can set actors to be attached to the mover, and move with it as it moves or rotates. This attach mover will be the center of the circular path of which our ship flies.

Under the properties of your attach mover, expand "Movement" and set the "yaw" of the "Rotation Rate" to about 500. This will make our mover slowly spin like a merry-go-round. Expand "AttachMover" from the main tree and set "Attach Tag" to "Ship".

Now let"s add ourselves a spaceship. Expand decoration from the actor tree in the class viewer. Now expand "UT_Decoration" from that menu. about one fourth of the way down, you will see actors with the names of "fighter1" and "fighter2". These are the ships you commonly see in Unreal. Add one of these somewhere along where you want it to fly. The distance between your ship and the attachmover will be the radius of your circle. Under the ship properties, expand "Events" and set the tag to "Ship". This will attach our ship to the attachmover. and make it fly around the circumference as it rotates. I"ve always found that the defualt size of the ship is too small. Expand the display tree. Under this, set the drawscale to a number between 1.5 and 3. You can test your level now if you want. If the ship flies too slow or too fast, change the rotation rate of the attachmover or move it further or closer to the ship.

A ship flying through the sky is awful perdy, but lets add some more frills to our design. How about some engine flares or some smoke trails? Somewhere under "UT_Decoration", there is a class called "UT_Flare". Add one behind each of the ship"s two engines. Open "city.utx" in the texture browser. Select the texture called "carflare". In the display properties, beside "sprite" and "skin", click "use" to apply the carflare texture to your engine flares. Under the advanced properties make sure "bstatic" and "bnodelete" are set to false and "bmovable" is set to true. Set the tag of your flares to "ship".

Now for our smoketrail. Under efects, there is a class called smokegenerator. Create one behind each engine of your fighter. Set their event tags to ship and then expand the smokegenerator tree. Set the number of puffs to some really large number (so it doesn"t run out of smoke), and then set the basepuffsize to about four or so. Set the frequency to about 0.05. You can always experiment with these variables later. Once again, under advanced properties, make sure "bstatic" and "bnodelete" are set to false and "bmovable" is set to true. A smoke generator won"t work unless you trigger it. Add a timed trigger and set the time to 0.01 or something. Type in "ship" for event, and leave its tag blank. This should take care of everything, but if you have any questions please email me or icq me at 46242443.


Wolf's Tutorial MOvers

Wolf's Tutorials: Movers Part 1

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Movers Part One (of Two)

Introduction

There are several types of movers in Unreal. I am not going to get into a WHOLE lot of detail on each kind, but I will cover the major types and give enough information on each one to get you started. As with anything in UnrealED the best way to learn is to do. I will give you a basic understanding of how different types of movers work, and then give you some specific properties of each and turn you loose. This is a two part tutorial. The Mover types covered in each part will be as follows:

Simple Movers Part One Rotating Movers Part Two Looping Movers Part Two Attach Movers Part Two

Simple Movers

Simple movers are made by adding a brush to the world you want to use for a mover, surrounding the brush with the red brush and intersecting it. Use the new red brush to add your mover. It is critical that the scaling and resizing of the brush be reset before intersecting. If you don't the mover will not work right. I usually use RESET ALL under the brush menu at the top, but you can also right click the red brush and select reset all. It is also crucial to have your textures aligned and applied correctly because one you intersect the brush, the mover will be identicle to it and cannot be changed.

Simple Door

So you got a level and you think you need a door in it huh? Well close the level you want the door in and start a new one. I will walk you thru making a simple door first, and then get into a couple other more complex doors. Once you learn the basics go back to your level and apply them.
Start off by loading a texture pack you like(I chose Starship). Next set your cube brush to 256 x 512 x 512 and subtract a room. Next reset your rush size to 256 x 512 x 32 and place it in the middle of the room, so you make a wall that divides your room in half. Add the brush. This is the wall we will place our door in.
Now we need to cut a hole in the dividing wall to place the door in. Reset the brush size to 256 x 256 x 32 and place it in the center of your wall and subtract. If you followed along you should have something like this:

Now, off to the side of the main room, build another room, this time make it 512 x 512 x 512. Pick a light texture for all six sides of the room. It doesn't matter what texture, this is just the room we are going to use to build our movers in and no one will ever see it but you. I will refer to this room as your builder room from now on. Ok, our hole for the door is 256 x 256 x 32. So we need to build our door 256 x 256 x 16. This way we will leave some room on either side of the door to make it look like a more realistic doorway. Set your brush size to 256 x 256 x 16 and make sure it is in the center of your builder room, not touching any of the walls and then add the brush to your world. Pick an appropriate door texture and apply it to the newly added brush.

Once you have the brush textured the way you want it, then reset the red brush and resize large enough to completely surround the door brush, but not touch anything else (I used 272 x 272 x 32). Position the red brush around the door brush and then intersect it and the red brush should wrap itself around the door brush.

Now take the newly formed red brush and move it to the hole in the center wall in the first room we made.

Now click the ADD MOVER button and you should get a purple brush in the door way. This purple brush will be the mover, and though it is invisible in the editor, it will look exactly like the brush we intersected. Now we need to set some of the doors properties. You'll need to either turn off the red brush (by pressing B in the window) or move it out of the way. Once the red brush is out of your way, then right click the purple mover brush to open up the Mover Properties window. There are only a few properties we need concern our selves with. First go to Object and InitialState. This tells the engine how we intend to open this door. The default is BumpOpenTimed. Like it sounds, when touched, this door will open for a specified amount of time and then close. Let's use that. Leave it at BumpOpenedTimed. Now open the Mover section. Whoa! Lots of properties there!

The first one to check is MoverEncroachType. This tells the editor what to do if someone is in the way of the door when it closes. The default is ME_ReturnWhenEncroached. With this setting, if you are standing in the doorway when the door closes, it will open back up until you are out of the way, then it will close. Let's go with that for now.
Next look at some of the other properties. We are going to use all the defaults for now, but often times you will want to set things like MoverTime (how fast it opens/closes), bTriggerOnceOnly (to open once and stay opened), bUseTriggered (If it will be trigger operated), and later on NumKeys (for how many key frames it will have).
Which brings us to Key Frames! Key frames are "points" where the mover will move to. Obviously you need these to tell the mover where to go. You can have 8 key frames (numbered 0 to 7). If you right click the mover brush you will see on the pop up menu under Mover Keyframes all the key frames numbered. We want to make our door slide straight up and down. One might think that when you move a mover to a certain position you would then select that key frame number.
This is OPPOSITE of how it works. We add the mover in it's 0 (or base) position. While it is there if we right click and select mover keyframes and keyframe 1 we can then move the mover to it's first key frame. When you move the mover to key where key frame one will be, then select keyframe 0 and it will automatically go back to its base position. Remember, When the mover is in the BASE or STARTING POSITION select KEY FRAME 1 and move it to KEY FRAME 1, then select KEY FRAME 0 and it will return to base. Think of it like "recording" where the mover will go. You pick one, move it to one and it remembers this path.
So while the mover is in it's base position where we added it, select key frame one, then move the mover straight up to where we want it to open to (I usually leave a little lip) and then select key frame 0 and the mover will snap back home.

At this point we have made a simple door that will slide up when touched, wait a couple seconds and then slide closed. Add some lights (on both sides of the door), add a PlayerStart, rebuild and run your map. Test the door a few times and make sure it works. If all went well the door worked just as expected.

Sounds

"But Wolf, my door is silent?" Why yes it is! That is because we didn't set any sounds to it. . . yet. Open up the mover properties and then click on MoverSounds. For normal doors and lifts we need to add a sound to each field, except MoveAmbientSound. The names of the different sounds should be self explanatory. In the browser change from Textures to SoundFX. Load an appropriate sound pack. I chose DoorsMod because I chose a futuristic theme. As you can see the sound file names tell you where to put them. Sounds with "end" in the name would go to ClosedSound and OpenSound, and ones with "start" would go in OpenedSound and ClosedSound. Easy enough, huh? once you have added your sounds the Mover Properties dialog should look like this:

Now you have fully functional door!

Double Doors

We could have just as easily made the door slide open to the left or right by setting different key frame positions. Let's make a double door that slides open to the side. Start by making a cube brush 256 x 256 x 32 and aligning it against a wall then subtracting it.

Now click on the starting room brush to highlight it. Let's make a copy of the first room. Right click and select Copy Polygons To Brush. Line it up like the image below and subtract it. You should now have another room, connected to the first by a small doorway.

Resize your cube to 256 x 128 x 16 and drag it into the builder room. Again, make sure it is floating in the air and not touching anything else. Add it to your world Select an appropriate door texture. Once you have it textured and aligned as necessary, intersect it with the red brush like we did the first door. Drag the red brush into the new door way we created between the two big rooms and align it to one side.

Now add a mover. Set the key frames so that the door will slide open to the side and out of the way like below:

We need two doors for this double door so go back to the builder room, intersect the new door brush again and bring the red brush back and line it up next to the first door. Set the key frames of this door to open the opposite direction of the first.

To get these doors to open simultaneously we are going to make this door open by a trigger. Select both movers (highlight one, then while holding control highlight the other) and open the Mover Properties dialog. Under Events set the tag to something unique (like slider1). This is the name of the door set the trigger will open.
Under Object set the InitialState to TriggerOpenTimed. While you have properties opened you can also set the sound like we did before. Now we need a trigger to open the doors. in the browser choose classes, go down to triggers and expand it. Near the bottom (next to last) you will see one that just says Trigger. Click on that (don't expand it). Now add the trigger to your room, and move it right in the middle of the two doors, near the bottom (see below).

Now open up the trigger properties and expand events. Under Event put the name of the two doors (slider1 in our example). Now, add some lights, rebuild and go check it out. When you approach the double doors they should slide open in opposite directions simultaneously.

Lifts

Our third simple mover will be a lift. A very simple one. You build a lift just as you do a door. First we need a place for the lift. Go to the newest room we made and duplicate it (copy polygons) and add it on top of the existing room. Now set your cube brush to 16 x 512 x 256 and position it like below. This will make a floor/ceiling, dividing the room in half height-wise.

Select a floor texture and add this brush to the world. Now drag the red brush into the builder room. As you can see this brush is too big (or rather, the room is too small) to intersect this brush without touching anything, so either expand your builder room or build another bigger one. Once you have the room big enough go back and duplicate the floor/ceiling we just made (Copy Polygons to Brush) and drag the brush into the now bigger builder room. Make sure it isn't touching anything and add it to the world. Select whatever textures you want, and intersect it with the red brush like we did the doors. Now drag the red brush to the room where we want the lift and lay it on the floor. Align it so it is opposite the floor/ceiling we added earlier.

Now add the mover and set keyframe one so that it is even with the floor/ceiling like below.

The only properties we need to change for the lift is under Object InitialState. Change it to StandOpenTimed. It works like bumpopentimed, but if we use that the lift will go up as soon as you touch the edge of it, leaving you behind. Standopentimed waits until your on the lift before it moves. Set the sounds for the lift, add a light in the upper part of the room and rebuild. Go try it out. Go on, I'll wait here.

Summary

You should have a pretty good idea of how to make basic movers now. You can set more keyframes if you want, but under Mover Properties mover set the NumKey to however many keyframes you have. Remember key frames start numbering at 0 so if you have just set key frame 3 then you have 4 key frames.

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


Wolf's Tutorial Movers 2

Wolf's Tutorials: Movers Part 2

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Movers Part Two (of Two)

There are several types of movers in Unreal. I am not going to get into a WHOLE lot of detail on each kind, but I will cover the major types and give enough information on each one to get you started. As with anything in UnrealED the best way to learn is to do. I will give you a basic of understanding on how different types of movers work, and then give you some specific properties of each and turn you loose. This is a two part tutorial. The Mover types covered in each part will be as follows:

Simple Movers Part One
Rotating Movers Part Two
Looping Movers Part Two
Attach Movers Part Two

Introduction

This is Part two of the Movers Tutorial. If you haven't read Part one yet, go back and do so first. I'll be here when you get back and I will make everyone else wait for you before we get started. :) In part one we covered basic movers, a couple simple doors and a lift. This tutorial will cover rotating movers and other types.

Rotating Movers

Rotating Door

This part would probably have been in the first tutorial since this first mover we are going to make is not a true rotating mover, but a simple mover that rotates on an axis. Let me explain.

The doors we made in part one were sliding doors. They slid up and down, or side to side. The door we are going to make now opens like a door in your house. It swings open on its side axis. They are pretty simple to make, but a lot of people don't know how. We will fix that. You will be making swinging doors in no time at all.

Okay, to start with we need a starting room and a builder room. I suggest using the NaliCast.utx textures for this tutorial. Make the start room 256 x 512 x 512. Make the builder room 512 x 512 x 512. Now make short hall way, 128 x 128 x 16 and attach it to one side of the room. Copy the first room and put it on the other side of the short hallway. You should have something like this:

Now the fun part! Go into your builder room and make a cube 128 x 128 x 16. Add it, then pick a good door texture (like SDOORN - it's 128 x 128). When you align the textures on your door, be sure to make the opposite side of the door go the opposite way. That is to say, you want the "hinge" part of the texture on the same edge on both sides of the door brush.

I mirrored the wall in those shots so you could see both sides of the door at once.

Once you have the door textures aligned, intersect the brush and drag it over to the little hallway between the two rooms. Light it up so it fills the hallway. Now, add a mover. Now when you highlight the mover, see that little red cross right in the middle? That is your PIVOT POINT. It is all IMPORTANT when making rotating movers! If you rotate the mover now, it will rotate on that cross as it's center point. Go ahead and rotate it and see then rotate it back. Now that might me cool for some effects, but not out little swinging door. We need to move that pivot point to a corner of the door. It is VERY easy to do. When the mover is highlighted, simply click the vertex you want to be the pivot point and the cross moves to that vertex.

Now when you rotate the mover, it rotates on the new center point, and you can see, that is how we want our door to open. With the door in it's original position, set key frame one. Now rotate the door to it's open position and click Key frame 0.

Now we have the door moving the way we want it we need to do something so it works right. But before we do , add a player start (where indicated below), add some lights, rebuild and test the map.

Notice that when we approach the door, it starts to open but then closes right back? That's because of the doors MoverEncroachType. The default setting is ME_ReturnWhenEnchroach. That simply means that if someone is blocking the door it will politely say "excuse me" and close again. We need to fix that if we want to be able to open the door from both sides. We could set it to ME_CrushWhenEncroach but that would cause our little player to explode upon impact with the door. That would suck because we wouldn't ever be able to see all the cool stuff on the other side of the door (not that there is anything in there yet, but our player doesn't know that!). Anyway, let's set it to ME_IgnoreWhenEncroach. This will cause the door to "pass thru" any blocking player. Not a very realistic effect, but sufficient for this step in the tutorial.

Rebuild and run the map again. Ahhh...much better. Well, almost. The door is "funny" the way it passes thru you when it opens. It's cool when you go back through it from the other side, but I can't live with that passing though me stuff! And it's silent! First go set the sounds like we did in the last tutorial. Now, reset the MoverEncroachType to ME_ReturnWhenEncroach. Now we need to add a trigger to activate the door. First set the mover's InitialState (under Object) to TriggerOpenTimed. Then under Events give it a unique tag (like "door1"). Add a trigger and set it's Event to the mover's tag. Now move the trigger in front of the door, set it far enough back so that the door won't hit you when you activate the trigger.

Now rebuild and try it again. Go on, I'll wait. HA! Gotcha. You couldn't get back through the door could you? That's because the door is only activated by a trigger and there is no trigger on the other side. There are two ways to do this. One, move the trigger to the center of the door and set it's collision radius big enough to activate it on both sides. The other is to duplicate the trigger and move the new one to the opposite side of the door. Let's take the first option.

Reset the collision radius on the trigger to 156. Why 156? Because the door is 128 units in length and we want to activate it before we touch the door (remember, if we touch it while it's opening it will just close again). now move the trigger to the center of the door.

Rebuild again and test. Presto! You have a swinging door that works! You probably noticed that if you kept moving forward once the door was activated, you still hit it and it closed. The work around is to reset the MoverEncroachType to ME_IgnoreWhenEncroach. The effect isn't nearly so Unrealistic (pun intended) when you actually see the door opening before you. Rebuild again and try it out. Now play with the door. Set it's encroach type to different things and see how it reacts, and play with the triggers collision radius. You should be able to find the best setting on your own.

Rotating Mover

The rotating door, though it rotates to it's key frames, is not a real rotating mover. It's time to actually build a real rotating mover now. You can start a fresh map, or continue working on the one you started with. It doesn't really matter. Either way, we are going to build the rotator in a new room. But first we have to decide what kind of rotating mover we want. For this tutorial we are going to make something fairly simple, just to get an idea of how to do rotators. Let's make a rotating wall trap. When we are finished it will look like this:

A Rotating brush is a brush that rotates on a specified axis. You don't need key frames for it to move. In UnrealEd (and every other 3d editor) there are three axes (the plural of axis) that we use to determine an object's location. They are X Y Z. You can differentiate these by looking at the 2D view window's properties and seeing that X is the top right window, and Y is the bottom right window. Z is actually the top view, because Z is up and down. A Rotating brush will move on these axis but the direction it rotates is determined using Pitch Roll and Yaw. If you have any flying experience (or simulator experience) you will understand these concepts immediately. If you don't then think of it this way:

  • Pitch= up/down (like a ball)
  • Roll=left/right (like a wheel)
  • Yaw=left/right on Z axis (like a revolving door)

[For a good explanation of Pitch, Roll, and Yaw go to this site: http://www.nasm.edu/GALLERIES/GAL109/NEWHTF/HTF541B.HTM]

Okay....first let's make a hall for it to go into. Coming off the second room in our little map, make a room 512 x 1024 x 512 so that it makes an "L" with the first two rooms. Like This:

Next thing we need to do is make another builder room. Our needs have outgrown the previous room, as the new mover we are going to make will be to big to properly fit in the old builder room. Go ahead and delete the old builder room and anything in it. Rebuild Geometry and then subtract a new builder room 2000 x 2000 x 2000. This should be plenty big enough. Once you have the room subtracted, then resize the cube to 512 x 16 x 512. Add the brush to the world, give it a wall texture and then intersect it like any other mover. This should make the mover a "wall" that will fill the hallway we made for it. We know we want this to be a rotating mover so we have to set that property before we add the mover. In the Browser, go to Brush, then Mover and click on RotatingMover.

Now move the red brush into the hall we made for it (somewhere in the middle) and then click on the Add Mover Button. If you highlight the mover and right click now, it should say "RotatingMoverProperties." now we have a rotating mover, but we need to tell it which way to rotate (see Pitch, Roll, Yaw above). We want this mover to rotate it's Roll, so that it is spinning parallel to the hallway.

So we need to set it to rotate on the Roll. To do that open up the RotatingMoverProperties dialog and near the bottom expand RotatingMover (see below). There are three fields here under the heading RotateRate. Oddly enough they are Pitch, Roll and Yaw. This is where you tell the engine how fast and which direction you want the rotator to move in. Guess which one we want to set? Right! Roll. And how fast? Well, let me tell you, 100 is pretty slow. So pick a speed about 1000 and see how you like that. Note: don't bother checking it now, we haven't activated the mover yet. Keep reading.

We also need to set some properties of the mover. First thing to do is give the trap an Event Name (something original and fun like....trap1). Next, under Object, set the InitialState to None. Under Mover, set the Numkeys to 0 (so the mover knows there are no key frames to worry about).

Add a light on either side of the mover, then rebuild and test the map. The mover should Roll end over end. Great. But what happens when you approach the trap while it's moving? Right, it goes back to the start and stops moving. That's because we have the Encroach set to ME_ReturnWhenEncroach. Open up the RotatingMover properties and under Mover set the MoverEncroachType to ME_CrushWhenencroach. Now rebuild and check it again. See what happens. Now if you run under the mover all is well, but if you touch it while it's moving you hear a scream and see body parts. But damn, that mover still goes awful slow! No too much of a challenge. Reset the RotateRate to 2000. That should do it.

Now we have a rotating wall in the middle of the hall you have to run under without touching it. Not a bad little trap.

Practice Makes Perfect

Now go build a rotating mover (any shape you want) and practice playing with the rotation direction (Pitch, Roll and Yaw) and with the rotation rates. You can make some really cool objects (not just traps) with rotating movers. Experiment and have fun!

Looping Movers

A looping mover is a mover that is constantly moving. Like our trap we just made. So technically you just made a looping mover. If you select LoopMover (like we selected RotatingMover) you will get a slightly different dialog box. It has nothing special (like the RotatingMover had is's own RotatingMover field section. No, it's all in the settings. You can set it to rotate (like we did the trap --only the RotationRate is under Movement). The only thing you need to set is under Object, InitialState. Set it to LoopMove. Let's make a quick one. Expand our hallway past the trap another 512 units (set the cube to 512 x 512 x 512 and place it against the hallway at the far (South) end. Subtract it. Back in the builder room make a cube 128 x 128 x 128. Give it a unique texture (I used Nalicast.utx Block2B) and intersect it. Now move the red brush to the new section of hallway and rotate it like this:

Move the brush near to, but not touching the South wall. If you're not already there, in the Browser select LoopMover and then add it to the world. It should look like this:

Now open the LoopMoverProperties and set the InitialState to LoopMove. Then under Movement set the rotation rate for Pitch to 2000.

Add a light and rebuild. Let's go check it out. You should have a cube slowly spinning against the wall. I know, not very practical, but hey, it loops and that is the point! I am not here to give you ideas for your levels, but to give you some tools to implement those wonderful ideas floating around in that twisted little head of yours! :) You may have noticed a weird effect on our mover. Only the side that was facing the light in the Movers "at rest" position was lit. There are a couple ways to combat this. One, select all the surfaces of your brush before you intersect it and set them to unlit. The other is to add lights all around the mover. One way of doing that is to give the surfaces of your brush (before you intersect it) the Special Lit property and then add lights all around it with the Special Lit (under Lighting) option checked.

Attach Movers

This is a cool type of mover. With this mover you can "attach" actors to it so that they move in relation to the mover. We will make three different Attach Movers in this tutorial.

Simple Attach Mover

The first is going to be a simple moving brush with an object attached to it. Start by moving your brush to the builder room and making the cube 16 x 128 x 128. Add it and give it a cool texture. Now intersect it and move it to the room where your PlayerStart is. Place the brush on the floor, in the northeast corner (upper right). In the Browser chooses classes, brush, movers, AttachMover and then press the ADD MOVER button. Set Key frame one to the Northwest corner (upper left) of the room. Now under Inventory-PickUp add an Armor just above the mover, but towards the north wall, away from the edge of the mover. Leave all the mover properties at their default except under AttachMover set the Attach Tag to "item1" (this is the tag of the attach mover and will also be the tag of the item we want to move with it--in this case the armor). Set the armor tag (under event) to "item1"

Now we have just linked the armor to the mover. The mover is set to BumpOpenTime so if we walk up to and bump the edge of the mover it should now slide along the floor taking the armor with it. Rebuild and test it out. Notice you can still pick up the armor. You can even ride the mover with the armor. This will work with other entities too. I have not played with too many different ones, but I have found that if you use a weapon it will move with the brush but you can't pick it up. If I discover how to do that in the future I will amend this tutorial. If you find out first, let me know!

Invisible Attach Mover

You can make a visible attach mover (or any mover for that matter) by simply selecting all the textures of a brush to invisible and then intersecting it and making the mover. Let me show you.

First go to the builder room and make a 32 x 32 x 32 cube and add it. It doesn't matter what texture you use because it will disappear shortly. Select any face of the brush and then right and open Surface Properties. Check the Invisible box. You brush should disappear in the 3D view. If you look in a 2D view it's still there. If you want to be able to see it in the 3D view then click the joystick ICON or click anywhere in the 3D view and then press P. Now resize the brush and intersect the invisible brush. Move the red brush to the start room and add an AttachMover on the south wall (opposite of the 1st attach mover) and place it near the ceiling. Set the key frames the same as the 1st attach mover. Now give the invisible mover a tag name under events (invis1) and add a trigger, giving the trigger event the same name as the tag on the invisible mover (invis1). Move the trigger to the middle of the room, near the floor. Set the mover's InitialState to TriggerOpenTimed. Set the AttatchTag in the mover to "item2" and add a Flare just underneath the mover, giving it a tag of "item2". Now rebuild and when you stand in the center of the room it flare should move across the floor and a couple seconds later move back. You can pick up the flare if you want. You can do some cool stuff with this if you use your imagination!

Moving Lights!

Which brings us to moving lights! There are a couple ways to do this. You may or may not have heard of the moving lighted brush. I can do that but with less than wonderful results. The best way I have found is using an AttachMover. Follow along and you can do it, too!

Start by making a hall running North off the first room. Make it 256 x 256 x 256. Now set the Brush to 256 x 256 x 512 and attach it to the new hallway like this:

Now, in the builder room we need to make another invisible brush. You can use the same 32sq cube we used before. Interesct it, take the red brush back to our new hall, and add an Attach Mover near the ceiling on the East end of the room.

Add key frame 1 at the far end of the room. Give the mover a tag of "movelite1" and an attach tag of "lite1" and make sure it's InitialState is TriggerOpenTimed. Add a trigger in the 256sq hallway, right in the middle (near the floor) and give it an event of "movelite1." Go to the Browser, choose Classes and expand Light. See the FlashLightBeam? Select it. Add a light just below the mover. Right click it's properties (making sure it says FlashLightBeam Properties) and give it a tag of "lite1" Rebuild and run the map. When you walk into the 256sq hallway the light should move down the hall, pause and come back. Cool, huh? :)

Wrap Up

We have learned a lot about movers in this tutorial. You have learned in a just a little while what it took me months to learn. As always, expand on what I have taught you and you can really do some amazing stuff with movers. The moving light thing is not widely known in the Unreal editing community and I thought about not adding it so I would have "a trick up my sleeve" when it came to releasing new maps. But that is not why I am writing these tutorials (obviously). It is to share what I have learned and make Unreal Editing a more pleasant experience for everyone brave enough to fire up the editor and attempt to CREATE something.

I wouldn't mind a mention in your readme file if you make a really kick ass level with the knowledge you got from these tutorials either. :)

Happy Mapping!

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


Advanced Doors

    By: Joe 'Verxion' Chott
    jc83151@goodnet.com

    FORWORD:

    This is the fourth tutorial I have written, it is starting to feel like I know what I am doing. :-)

    ABSTRACT:

    This tutorial goes over doors. Not just simple doors. DOORS. Complicated doors with bells and whistles. We don't start there though. We make a simple door, and then adjust it over and over to make it more and more impressive. To give you an idea of what I am covering, I will start with a simple door that opens in one piece when you approach, and ends up with a door that has sound effects and moving parts. You can basically follow the tutorial until doors of the level you want are covered. :-)

    ASSUMPTIONS:

    This is an advanced tutorial. I assume you know quite a bit about the editor to be able to finish the tutorial. I will try to make the first stage or two of the tutorial easy enough that if you are new to the editor you should come away being able to make at least simple doors. But to finish the whole tutorial, you will need to know your way around the editor fairly well.

    TUTORIAL:

    PHASE ONE:

    First off, make a room at least 512x512x512, and place some textures onto it.

    caption: here, you see the initial room.

    Next, we need to make a wall across the room, such that we seperate the room into 2 rooms. Once we have made the wall, cut a rectangular hole in it such that it looks like a doorway.

    caption: here, you see the wall seperating the rooms, and the adjoining doorway.

    Now, in my case, I have made the depth of the doorwar especially thick to make the construction of the more complicated types of doors easier to see. If you are just making a simple door, you would want to make the wall and hence the doorway of a fairly small thickness.

    Next, you need to make a door. Since this door will be a "mover", we will build it up in the air, texture it, intersect it, copy the poly's to the brush, and place the mover. Was that a lot of steps? Well, the first time through, we will show all the steps, don't worry.

    caption: this is the door, suspended in mid air.

    Now, you need to intersect the door. You do this by making your builder brush larger than the door itself, WITHOUT scaling. If you scale it, your door will end up being hollow, and you will be able to walk through it. Right click on the block symbol in the toolbar and adjust the height, width, and breadth under "cube properties".

    caption: This is the door, surrounded by the builder brush.

    Now, intersect the door. Next, right click on your builder brush, and choose "copy polygons -> to brush". Now, move your builder brush to where the door should be when it is "shut". Once it is there, go ahead and delete the door suspended in mid air (or, if you think you may have done something wrong, go ahead and leave it there for a while until you are sure the mover is working).

    Now, click on the "add movable brush" icon in the toolbar (the cube with the swirls coming out of it).

    caption: This is the mover, placed in the doorway.

    Next, we are going to make a place for the mover to move to above its position. Grab your builder brush, and put it just above the mover, but aligned to the mover in all other dimensions. Choose a texture for this slot, and subtract.

    caption: Here you can see the mover with the builder above it.

    Now, right click on the mover, and select "Mover Keyframe -> Key 1". Now, slide the mover straight up into the slot we made for it. Ok, next we need to put it back on keyframe 0, so select the mover, right click on it, and select "Mover Keyframe -> Key 0". Guess what? You are ready to try this door out. Hit F8, rebuild, and then hit ctrl-p to try the level out. The door should go up in the air when you bump into it. Give it a try.

    PHASE TWO:

    Well, we made a door. We made it move. Is that an advanced door tutorial? I don't think so. Notice that the door we made only moved when we bumped into it. And further, it made no sounds at all. Although personally, I like doors to work when you bump into them (I think it is more realistic), the doors in the single player game don't work like that. And I shouldn't be restricting you to something, should I? :-) Another good point would be that for a door to move up vertically, we probably aren't LIFTING it, so it would make sense for it to move by itself, and if it moves by itself, then we shouldn't HAVE to bump into it.

    Ok, enough rambling. What we are going to do now is gradually adjust our door bit by bit. I will name each new modification to the door a "PHASE" so you can clearly see when we are about to do something new to the door, and have finished a modification. Our first modification is a very very simple one. Lets add some SOUND! :-)

    Right click on your mover, and choose "Mover Properties". Take a look at the section called "Mover Sounds". For right now, we will just mess with the "ClosedSound" and the "OpeningSound". I think once you see these, you will understand the process. You will probably want to do something for "MoveAmbientSound" occasionally. Select "ClosedSound", and click on the three dots to the right of it. You will notice that "SoundFX" is selected on the far right toolbar in the editor. Click on the "Load" button over there, and choose "DoorsAnc". For ClosedSound, lets choose "adend53", then in our properties dialog, click the button marked "use". You will see the sound listed there. Now, do the same thing for "OpeningSound", except choose the sound "adend52". Close your mover properties window, do an F8, rebuild, and ctrl-p the level. Now, when the door moves you should hear sounds. :-)

    caption: Here, you see the filled out "Mover Properties" dialog, complete with an ambient move sound.

    PHASE THREE:

    Didn't that seem more realistic? Sounds add so much to the realism of a level in my opinion. Ok, next, lets make it so you don't have to bump into the door to open it. What we will do is make a trigger that opens the door when we walk near it.

    First thing we will do is name our mover. Why do we need to name it? Well, triggers affect specific objects (these objects all have the same tag), and if the objects don't have a unique tag name, the trigger won't have anything to act upon. So, right click on your mover, and choose "Mover Properties". Next, choose "Events", and you should see a section marked "Tag". Change it to say "door1". Now we have a unique tag name to use for our trigger. But since we are already in our Mover Properties section, lets change one other aspect of our mover. If you remember, bumping into the mover caused it to move. What we want now is for the trigger to cause the mover to move. So we have to change how the mover acts. Open the section called "Object", and click on the section marked "InitialState". You will see it is currently marked "BumpOpenTimed", well, that pretty well describes how it works right now. Choose the drop down arrow next to it and change the value to "TriggerOpenTimed". Ok, now our mover is all setup to be triggered.

    caption: These are the relevant sections of the mover properties with the new values for being triggered.

    Ok, so it should make sense to you that we need a trigger, right? :-) Lets add one. Go to the Classes section on the "Browse" drop down menu. This is on the right hand side of your editor screen if you didn't know. :-) You will notice an item at the bottom called, interestingly enough "Triggers". Well, expand this section, and expand the section inside called "Trigger". Quite a few options eh? We aren't going into them all now. We just need a simple trigger.

    Choose "Trigger", and place it on your map. I have said before that I prefer to add items in the XZ or YZ views (the two views on the right of the editor by default). The reason I prefer to do this is that you place the item at the correct Z height, and only have to move it to the correct XY position, easily done on the overhead map. And on simple maps like this, it normally picks the right XY position for you. :-)

    Put your trigger on the floor, right in front of the door, perhaps 5 feet or so in front of it, in the middle of the doors' width. Ok, now we need to modify the trigger properties. Go ahead and right click on the trigger, choose "Trigger Properties", and then choose "Events". Now, change the "Event" from none to "door1". This will cause the door to be acted upon by the trigger. Just fyi, under "Trigger", you will find an item called "TriggerType", and this has some interesting different ways of triggering the trigger. But the default value is fine for us.

    Ok, do an F8, rebuild, and ctrl-p. When you get into the level, be sure to walk in a straight line for the door. By default, the trigger area is pretty small. Keep moving around until you find it. (If you placed it right in front of the door like I described, it shouldn't take but a second to find it).

    You will notice that if you move through the doorway into the other room that you will not be able to go through the door. You have a "one way door" right now because there is no trigger on the other side. As an exercise, you might want to add another trigger in the other room and make sure you can get through the doorway from either side. Just follow the same directions for the other room.

    You will also notice that there is a red line drawn from the trigger to the door. The red lines on maps allow you to easily see the "cause and effect" of your triggers, ie, what area has the trigger, and what the trigger is effecting. Do not forget this, because when your maps get very complicated, without the lines, it would be very easy to get lost.

    One last item for this phase. If you wanted to, you could increase the area of effect of the trigger by increasing the "CollisionRadius". This is located in "Mover Properties" under "Collision -> CollisionRadius". This will allow you to be in a less specific area. You can even increase the radius fairly high, and place the trigger right under the door, then you can approach the door from either side, and activate it with only one trigger.

    PHASE FOUR:

    Man oh MAN is this a long tutorial or what? :-) And I am not even getting paid for this. What was I thinking? Oh well, hopefully people will benefit from this. Next, lets make a panel on the wall next to the door that causes the door to open. We will be using the trigger to cause this to happen.

    If you increased the CollisionRadius in the previous phase, reduce it back down to something like 150. If not, go ahead and leave it where it is.

    Now, take your builder brush, and create a rectangular panel looking shape, that isn't too deep. Choose some appropriate seeming texture, and place the builder brush to the left or right of the door, at a height that your character can walk up to. Next, move your trigger to be right in front of the panel, and in the middle.

    caption: I made mine as a small button type panel near the floor to the left of the door.

    Now, if you positioned your trigger in the right spot, all you should have to do is F8, rebuild, and ctrl-p to try it out. If you bump into the panel, the door should open. You can probably remember some spots like this from in the single player game.

    Again, unless you put a trigger on the other side of the door, this will be a one way door. Remember, you can simply duplicate this little panel and put it on the other side of the wall with a corresponding trigger to be able to open it from either side.

    PHASE FIVE:

    Yup, still here, still adding stuff to this door. :-) Well, we are gonna get a bit fancy now. Let's make a mover out of our panel. We will make it move when we push it. Add some sound to it, and it will seem that much more real! Ok, surround your panel with a non scaled brush ( refer to the first mover we made if you forgot how to do this), and intersect it. Subtract from the wall a spot large enough for the panel to slip into, then move the brush back to the panel. Then, copy the polygons to the brush, move the brush out of the way, and delete the original panel.

    Now, move the brush to where it is just at the edge of the hole in the wall that you made. Add special, and voila, we have our mover. Move the brush out of the way. Now, right click on the mover, select the second keyframe (keyframe 1), and move the mover into the hole in the wall. Now, right click on the mover again, and put it back at keyframe 0. Add some sound if you want (You might use adend50 for the switch opening sound). Make sure your trigger is right on top of the switch. Do an F8, rebuild, and ctrl-p to play it.

    Now, when you walk up to the switch, the switch should move into the wall (and make a sound if you did that), and simultaneously, the door should open up. Pretty decent eh?

    PHASE SIX:

    Well, I don't know why I keep going on this, but I am. :-) We are going to make one final modification to this whole thing. We will make the door open as two pieces, and have the two pieces open to each side. What we will do first is delete the subtracted region above the door (since it won't be going up anymore), and removing the mover for the door itself. But leave the switch and the trigger there, we will be needing them.

    After you have removed those items, lets build the new door. We will do this by making the same shape for the new door, again, up in the air. Next, we will subtract a small section from the middle of the door. This should be a narrow slice down the center of the door vertically.

    caption: Here, you can see the door, complete with a vertical slice down the center.

    You need to intersect the two halves and place the movers. To do this, select your brush, reset the scaling again (if you forgot how to do any of these steps look at the previous phases in this tutorial), and enclose the right half of the door with the brush. Make certain that only the right half of the door is enclosed, no part of anything else being in the enclosure. Now, intersect the door half.

    Now, move the builer brush to a position in the door frame such that if the right half of the door was to slide fully to the right, it would have someplace to slide into. Make certain it is in the correct position in all dimensions. Once you are certain of this, make certain that if you were to subtract the brush, that it would create a visible hole in the side of the door frame. What I mean by this is that if your brush is too far into the wall, you would subtract it away, and see no visible difference (of course, if that ends up happening, you can just hit undo and try again). Once you think it is all lined up correctly, subtract it away from the doorframe. You should see a spot for your door piece to slide into now.

    Next put your brush so it is exactly on top of the right half of your door again. (This should be where the brush was when you intersected it before). Now, right click on the brush and do the "Copy polygons -> to brush". You are ready to place the mover for the right half of the door. Put the builder brush just to the left of the hole you cut out for the door half. In this position, the door should cover half of the doorway. Make certain it is aligned in every dimension, and when you are certain of this, click on the "add mover" icon (the block with the swirls coming out of it).

    You have done half of the door. Repeat the above procedure exactly for the left half of the door. When you have finished the process, delete the door and the subtraction down the middle of the door from the middle of the room (this is the door that you intersected that I am asking you to delete).

    caption: Here, you can see the two movers in place, ready to be told how to move.

    We are nearly done! Select the right hand door mover, then hold the control key down and select the left hand door mover. You should now have them both selected. Next, right click on one of them, choose "Mover Properties", and we will modify a few settings. These will be the same as before. Under "events", change the "Tag" to be "door1", and under "Object" and change the "InitialState" to be "TriggerOpenTimed". You should now see a red line on your 2d views that goes from your trigger to your door mover pieces. If you don't, something went wrong, go through the procedure and try to find what it is.

    Next, and this is VERY critical, unselect your movers, and select ONLY the right hand mover. You do not want them both selected for this part. Right click on the mover, and select "Mover Keyframe -> Key 1". Now, move the mover so that it is in the recessed portion of the wall, in the hole that we made for it. If you want, you could leave a little bit of it still sticking out into the doorframe area. When it is in the position you wanted, right click on it again, and select "Mover Keyframe -> Key 0". Next, do the same thing for the left piece of the door, putting it into the hole on the left.

    If you want, you can add sounds to the door pieces like we did before. As I mentioned earlier, I think the sounds add a lot to the feel of a level.

    Guess what? You are ready to try this thing out! F8, rebuild, and ctrl-p the level to see how it works. You should be able to hit the switch on the wall and see the two pieces of the door move into their respective chambers, making room for you to walk through the doorway. As before, if you want to open the door from the other side, you will need a trigger on that side for it to happen, but I think you are advanced enough now to know how to do that! :-)

    Take this tutorial, go through it a couple of times until it seems clear to you what the steps are. Then, design some doors on your own that make use of the principles I have shown you.

    One last thing. I will be adding to this tutorial later on to give you a door that has moving gear pieces in a VERY elaborate technique such that you can see the actual mechanism that opens the door. This tutorial was long enough and SOOOOO many people were emailing me that they wanted it, that I have decided to release it now. I will add to the tutorial later on.

    Good luck, and may all of your levels be awesome! :-)

    -Joe Chott (AKA Verxion)


Elevators

Basic Elevators

By: Joe 'Verxion' Chott
jc83151@goodnet.com

    Whelp, this is my very first tutorial for UnrealED. I sincerely hope people will like it. If you find any problems with it, PLEASE email me at jc83151@goodnet.com, and I will make every effort to improve the tutorial. Before I go any further, let me explain that I am very new to Unreal, and to the "editing" scene as well. I am currently a programmer/security analyst at Boeing. But I used to do desktop publishing for a living, and I have found that a lot of what I learned there is applying to UnrealED. I am also hopeful that the fact that I am new to editing levels in general will make my tutorials more useful for people new to this program.

    ABSTRACT:

    This first tutorial is going to go over simple elevators. Let us consider what the pieces are that we need to get elevators to work, and what some of the terms are that we will be using. The elevator itself will be a "mover". A mover is simply a "brush" that is purple in color, and is capable of moving. The mover will move through a series of positions called "keyframes".

    ASSUMPTIONS:

    You know how to make a room, put a playerstart in it, how to move and shape your brush, and deal with textures.

    TUTORIAL:

    First off, make a room at least 256x256x256 (although this will be somewhat cramped). Next, reset your brush, and make a cube that is squashed such that it would be short enough to walk onto. Make sure there is enough height and width that you can stand on it. Put this brush in mid air. Choose a texture, and "add" it into the room.

    caption: here, you see the textured elevator floor in mid-air

    Now, right click on your brush. Choose "reset -> reset scaling" This step was very important. Let me explain why. If you did not reset the scaling at this point, the elevator would not work properly, instead, it would allow you to walk THROUGH it instead of on top of it. So if, after making your elevator, you find that you can walk through it and it doesn't work right, this was probably the step you messed up on. :-)

    Next, move your brush so that it surrounds your elevator floor piece. Once you are certain the brush fully surrounds it intersect the elevator floor. (To do this, you can either click on the intersect button in the toolbar, or go to the "brush" menu, and choose "intersect). Now, right click on the brush, and choose "Copy polygons -> To brush". This will copy the textures and the shape of your elevator floor into memory.

    The step I am about to give you can happen anytime that you choose. If you are confident that you did the previous steps right, you can do this step now. If you think something may have gone wrong or are unsure, you can wait to do this step until after you try your elevator. This step involves the elevator floor you just copied. It is hanging in the middle of your room. You need to delete this at some point. :-) You can either do it now, or after you know your elevator works.

    Next, place your brush onto the floor where you want the elevator to be. (This is the spot the person will walk onto in order to activate the elevator.) Once you have the brush positioned where you want it, click on the "add mover" icon in the toolbar. (The box with swirling mist coming out of it.) Move your original brush out of the way, and you should see the purple "brush" that is called the "mover".

    caption: Here, in purple, you can see the mover at keyframe zero.

    Next, we need to tell UnrealED where the elevator is going to go. Right click on the purple mover, and choose "Mover keyframe -> Key 1". Now, in the perspective view, while the mover is selected, hold both mouse buttons down and translate the mover vertically. I recommend doing this in the perspective view because you can see clearly where you are placing the elevator, and you can easily restrict the motion of the mover to the Z axis only.

    caption: Here, in purple, you can see the mover at keyframe one.

    Almost done. Just right click on the mover one last time, and put the keyframe back to zero (mover keyframe -> Key 0). This sets the initial position of the mover for when the map starts. Now, you can F8, rebuild map, and ctrl-p it to try your new elevator out!

    Good luck. :-)


By

 Moving Doors and Elevators with Movers

By: Radagust
lemon_the_redbaron@yahoo.com

Moving Doors and Elevators with Movers

You ever wonder how the makers of Unreal made their doors and elevators work on switches to move them with out a trigger? Well I figured out how and will try to make it as easy as possible. This Tutorial deals with moving doors and elevators with other movers.

Assumptions:

I assume that you know how to make rooms, doors, elevators, and player starts.

Tutorial:

Okay first thing is to make a room any size you want. Go ahead and add your playstart, and lights into the room. Next make a block that goes across the width and height of your room, make the breadth of the block not as large as your original room. Next make another block that goes all the way through the one you just made, it should be the same breadth of your block, make the height and with what you want. Then place the block inside of the other block make sure that the block is lined up with the wall on both sides of the wall before you subtract it. There now should be a hole going through the block and you should see the other side of the original room. Now make a block that fits inside the hole, the height and width should be the same as the hole. The breadth should be less then the hole unless you want a thick door then just leave the breadth the same. Once you have your brush for the door built move it outside of your original room up into the air. Now subtract your brush. Once you have it subtracted make another brush and surround the door. When you have it so that nothing sticks outside of the brush press the intersect button. I’ve always had trouble with this step. After it is intersected, select copy and copy polygons to brush. Now move your brush back to where your hole is. Once you have it positioned in the hole where the brush touches both sides of the wall and is moved where you like it press add mover. Now after you have added mover, move your brush into the wall right beside your mover and subtract it. There should be a hole going into the wall for your mover to move into. Now select your mover and set mover keyframe to 1. Now move the mover into the hole that you made for it. Once you have it inside of the hole in the wall select your mover again and this time set your move keyframe back to 0. Now that the door moves into the hole select your mover again this time go to mover properties. Under events leave event none and change tag to door 1. Now go to object and set that from BumpOpenTimed to TriggerOpenedTimed. Now make a new brush 16,16,16,16 usually works for a switch. Take your brush back up outside of your room and subtract it. Build a brush around it and intersect it. Then copy polygons to brush again.

Now move your brush down right beside the door, make sure that the brush is touching the wall and is low enough for you to run into. Now press the add mover button. Now take your brush and go back into the wall right behind your mover and subtract it. You now should have a hole in the wall. Okay select your mover and set it’s keyframe to 1. Now move your mover back into the hole that you made for it. Once it is in the hole in the wall select your mover and set it’s keyframe back to 0. Now select your mover and go to mover properties. Go to event now change event to door1 and leave its tag alone. There should now be a red line going from your switch to the door. Now your ready to try it out. Hit F8 and rebuild the level. Go in and try the door out if you want to add sounds to it you can.

Elevators are exactly the same. Just build your brush big enough for the play to walk onto and place it on the floor and add mover. Set it’s keyframe, go to event and change tag to lift 1., go to object and set it to trigger opened timed. One more thing you should set the mover move time to 8 or your elevator will be too fast. Now build another switch the same as before. Place it on the wall low enough to run into, and place a hole in the wall for it to go into. Set it’s keyframe, go to event and set event to lift 1. There should be a red line going from the switch to the lift. Now just rebuild the level and try it out.


By

Basic Mover Overview

By: BEG

1. Build your rooms, hallways etc. Place your lights, playerspawn and other actors.

2. Create a seperate room somewhere away from your level.

3. Build your doors, lifts, etc. like you would any brush. This will act like a template for your mover.

4. Texture your "template" how you want your mover to look like.

5. Use your red builder brush to encompass your template brush and Intersect it. (See notes for warning)

6. Right click the red builder and select Copy Polygons -> To Brush. This will copy the texture from your template and ultimately to your Mover brush.

7. Align your red brush into the world where you want your Door, lift, or whatever into your world.

8. Click on the Add Mover button. Your mover is now in place and ready to have its keyframes set.

9. Move your red mover out of the way so you can see your Mover(Purple brush). Left click to select the mover. Right click Properties -> Mover Keyframe -> Key 1. Move your Mover to where you want it.

10. Right click the mover and goto Properties -> Mover Keyframe -> Key 0(Base). This will reset it back to its original position. 11. Rebuild your level and test it out, you should now have working and textured movers in your level.

BEG's Words of Wisdom -

Movers are very integral to every level, you will be able to add doors, elevators and other goodies you can think of. Watch for my upcoming Advanced Movers tutorial for Complicated doors, multiple keyframed movers, and maybe some other tricks. Movers can also be used in combination with Triggers(see Trigger tutorials) for even more cool things your can do with Movers.

Notes -

Before your intersect your "template" brush make sure you reset the scaling on your red builder(Brush | Reset | Scale). If your red builder had been scaled previously it will cause clipping problems and your player will slip through your mover.


Lode's All about Movers Tutorial

By : Lode Vandevenne

lode@altern.org

Lode's Unreal

You can download the zipped version that contains the example maps.

Table of contents

Part I

Assumptions
Introduction
What is a mover?
A Lift in 6 Steps
Creating a basic lift (more detailed explanation)
Creating a basic door
Creating a rotating door
Movers with multiple keys
Moving the mover around in the editor
Basic Mover Properties
MoverSounds

Part II

Things you like to know
Rotating movers
Movers & lighting
Triggered movers
Looping Movers
AttachMovers
Attaching movers to another mover
Mover events
The ElevatorMover
The AssertMover
The GradualMover
 ReturnGroup
More Mover Properties

Part III

A door that opens by pushing a button
A train with a button
A wiggling boat
 A Real "Office Building" Elevator

Other

Download
The Future
Contact

Assumptions

I assume that you can work with basic elements of the editor and you can make a map. If you don't, please read a beginners tutorial first.

Introduction

It's not difficult to make a basic mover, like a simple door or lift, but you can do so much more with movers. This tutorial will teach you everything about movers. Every propertie and every movertype is explained.

This tutorial is optimised for UEd2, but if you have UEd1, you can use it as well, because these two versions don't differ that much. And I've added remarks for UEd1 when there is a difference. You can of course apply the official UT 420 or higher patch to get UEd2. I recommend patch 436, because this one adds even more new features such as realtime preview of skyzones, editing the textures of a mover and a replace textures function.

There are 3 parts in this tutorial:

*Part I is for beginners and describes the basics of creating simple movers.
*Part II is for intermediate and advanced mappers, and contains a description about all mover proporties and classes.
*Part III will use everything you learned in the previous two parts to create some cool stuff. A door with a button, a train with triggers in it, a boat that wiggles and sails at the same time and an elevator with inner and outer doors, that can go and stop at 4 different floors.

Part I

What is a mover?

A mover is a moving brush. It can move to different locations and/or rotate around an axis. Most movers have several keys. Key0 is the begin position, the mover will wait there until it is triggered. The other keys are the locations the mover will move to when activated. It will move through all the other keys until it reaches the last one.

You can recognise movers in the editor because they are purple. In the 3D view, you can see the movers through the walls.

Movers can be used for doors, lifts, trains, boats, buttons, rotating rocks in the sky, or anything else that moves.

In this tutorial, when I say the mover is "open" then I mean it is at its last key, and when it is "closed" it is at its first key, Key0. A "closing" mover is one that is moving from the last to the first key, and an "opening" mover is one that is going from the first key to the last one. So even if the mover is not a door, I will still use "open" and "close" for these situations.

A Lift in 6 Steps

  • Make a template of your mover with normal brushes
  • Intersect your template with the red brush. Make sure it's transformed permanently!
  • Place the red brush at the down position of the lift and press the Add Mover button
  • Right click on the purple mover brush, expand Movers and press Key1
  • Move the purple brush to the up position of your lift
  • Right click on it again, expand Movers and press Key0

Done.

Creating a basic lift (more detailed explanation)

The most standard mover in the Unreal engine is a mover that starts moving to a new position when you touch it, then waits for a few seconds, and then returns to its original position.

We are now going to make a lift that starts rising when you step on it. Please make a large room now.

To add a mover at the location where your red brush is, press this button: . its located in the toolbar on the left, under the add, subtract, intersect and deintersect buttons

In UnrealEd1, you have to press the button that looks like this: .

When you pressed the button, you see a purple brush appear at the red brush. That's a mover! However, this mover will not do anything yet when you touch it. Also, this mover probably doesn't have the textures and shape you want. In version 436 of the editor, you can view and edit the textures of the mover by right clicking on it, expanding Movers and then clicking Show Polys, but then still the shape isn't correct. Your mover must be one single brush, so if you want it to have more complex forms than a cube, a sphere or whatever, you can't create it this way.

That's why most people first make a template of the lift with normal brushes, then intersect the whole thing, and then use the red brush to add the mover.

Delete that mover you just made, because now you will make a good one. First make a template of the lift. You can make it at any location, the best place to make it is in a large room outside your map, or if your map is a large outdoor map you can make it somewhere in the sky. Use normal brushes for this template, I mean the blue and the yellow ones. Give it the textures you want, align it, apply the texture properties you want, vertex edit it if necessary. When the lift is finished, rebuild geometry and then move the red brush around the lift. Make sure the lift is completely inside the red brush, and there is nothing else inside the red brush. Also make sure the red brush is not scaled or rotated, so if it is right click on it and use Reset Scaling and Reset Rotation, or use Transform Permanently. Otherwise the mover will have a weird collision.

Position the red brush around the lift before intersecting

Now intersect by pressing the Intersect button [image]. The red brush now has the same shape as the lift.

The red brush after intersecting

It is safe to delete the template now, you won't need it anymore, except if you want to intersect the same lift again later.

Move the red brush to the begin position of the lift, this means the position the lift will have when down. Now press the Add Mover button [image]. The lift looks like purple lines in the editor, if you start the map now in the game it will look like the template you created earlier.

The "down" position of the lift

However it will not yet move. To make it working you first have to give the lift a second key. Do this by right clicking on the purple mover brush, then in the menu that appears expand "Movers" and there select Key1.

Selecting Key1

After you did this, place the purple mover brush to the position you want the lift to have when up.

The "up" position of the lift

The mover brush now has two different positions: Key0 (base) is the "down" position, and Key1 is the "up" position. If you right click on the mover again and choose Key0 (base), you will be able to see the original position again (down). Now your lift is ready and works! Rebuild your map, save it (don't forget to place a PlayerStart in the map), and play it. When you step on the lift, it will rise, and after a few seconds descend again automatically.

Creating a basic door

To make a sliding door, do exact the same as you did with the lift, only now make a mover that looks like a door and place the second key now on the left or the right of the door, or above the door to make one that opens into the ceiling.

Creating a rotating door

Most people have rotating doors in their houses, and not these futuristic sliding doors. To make a rotating door, again make a mover that looks like a door. But now you don't have to move the second key. Rotate the second key the same way as you would rotate a normal brush with the rotation tool, as you can see on these pictures:

Key0 of the rotating door

Key1 of the rotating door

You now learned how to make lifts, doors and rotating doors. You can make any other moving object the same way. The Unreal engine doesn't see any difference between lifts, doors, trains, or whatever. It just sees movers as things that move between different Keys.

Movers with multiple keys

The lift and doors you just created use only 2 keys: Key0 (base) and Key1. You can also make movers with more than 2 keys, with a maximum of 8 keys. If you make such a mover with for example 4 keys, it will, when activated, move from Key0 to Key1, then to Key2 and then to Key3. There it will wait for a few seconds, and then it will return to Key2, then to Key1 and then back to Key0 where it will wait until it is activated again. To give a mover multiple keys, do the same as you did with Key1 in the lift example, but this time do it for Key2, Key3, etc... as well. But that's not all, you also have to tell the mover how many keys you want it to use. Right click on the mover and choose "Mover Properties". In the window that appears, expand "Mover" and there set NumKeys to the number of keys you are using. So if you use Key0, Key1, Key2 and Key3, set NumKeys to 4.

The Mover Properties

The KeyNum propertie does the same as what you have done before to select a key of the mover. When you right click on the mover, expand Movers and there choose Key1, that is the same as setting KeyNum to 1 in the Mover Properties.

Most of the times you set KeyNum to 0 before saving and playing the map, but if you leave the KeyNum for example to 1, this gives another effect on the mover: if Key1 is the up position of a lift, and Key0 its down position, and you leave it to Key1 before saving, the lift will be up when you start the map. It will stay up until you activate it by touching it. Then in will wait for a few seconds, and then go down. Now it will stay down forever until you touch it again, but now it will not stay up forever, but go back down after a few seconds. So once you touched it, it acts like as if you set KeyNum to 0 before saving the map.

Moving the mover around in the editor

You can move almost anything in the editor (brushes, actors, ...), even movers. As you know by now, movers have more than one location, each Key has its own location. To move a certain Key of the mover, you first have to select that key and then move the mover around in the editor. If you move Key1, Key2, Key3, ... , or Key7, only that key will move. However, if you move Key0, all other keys will move as well. So if you made a lift that can rise etc..., and you want to place it somewhere else in the map, you only have to move Key0. Key1 will follow then.

You can move the mover, but you also can rotate it. If you rotate Key0, the other keys will rotate as well, but the will not move. This means if you have a door like this (the bright door represents Key0, the dark one Key1):

and you rotate Key0 90°, it will look like this:

and not like this as you might have hoped:

This means, if you have made a sliding door and want to use the same door again, but rotated 90°, and duplicated the first door and then rotated it, you have to reposition the second key before the door works the way you want it.

Basic Mover Properties

Every mover has a lot of properties, for example to change the speed, the sounds, etc... of the mover.

To open the Mover Properties of a mover, right click on it and select "Mover Properties". In there, expand "Mover".

The Mover Properties

The most important Mover Properties are:

-bTriggerOnceOnly: If this is true, the mover will work only once, and after that never anymore.
-BumpType: Determinates what will make the mover start (if it is not a triggermover).
BT_PlayerBump: the mover will be activated when touched by a player
BT_PawnBump: the mover will be activated by a pawn, like rockets, crates, Nali, etc...
BT_AnyBump: the mover will be activated by players and by pawns
-KeyNum: the mover key you are editing, also the key the mover will have when you start the map.
-MoverEncroachType: this determinates what the mover does when a player blocks it.
ME_StopWhenEncroach: the mover will stop when it hits you. It will almost never move again, not even if you touch it. However, if you have another mover that is set to ReturnWhenEncroach, and this mover has to return because it has hit a player, all the stopped StopWhenEncroach movers with the same tag will move again. This has to do with ReturnGroups, as you will see later.
ME_ReturnWhenEncroach: it will return to where it came from, wait a while and then try again.
ME_CrushWhenEncroach: it will kill you when it hits you
ME_IgnoreWhenEncroach: it will go through you and continue its way as if nothing has happened
-MoverGlideType:
MV_MoveByTime: the mover will move without acceleration (constant speed)
MV_GlideByTime: the mover will use an acceleration when it starts (positive acceleration) or stops (negative acceleration) moving.
-MoveTime: the number of seconds the mover uses when moving from one key to another. This means that if your mover uses 5 keys and MoveTime is 1, the mover will need 4 seconds to open or close, because it has to go 4 times from one key to another. If you set MoveTime to 0, the mover will "flash" to the new location, however you will not be able to use this as a teleporter, except if there are no walls or objects to obstruct the player on its path.
-NumKeys: the number of keys your mover uses.
-StayOpenTime: how long the mover will wait before returning to its begin position.

MoverSounds

In the MoverSounds expansion of the Mover Properties, you can determinate all the different sounds the mover can use. There are 5 different fields, each of them for another situation of the mover:

ClosedSound: the sound the mover will make when it has finished closing
ClosingSound: the sound it will make when it starts closing
MoveAmbientSound: the sound it will make while moving; this is a looping sound
OpenedSound: the sound the mover will make when finished opening
OpeningSound: the sound it will make when it starts opening

To select a sound, first open the Sound Browser by opening the View menu and selecting "Sound Browser...", or press the speaker button [image] in the toolbar. Then, open the File menu of the Sound Browser and choose "Open...". Make sure you are in the Sounds folder of your Unreal Tournament. There are two packages that have good door and elevator sounds: DoorsAnc.uax and DoorsMod.uax. The DoorAnc.uax has ancient door sounds, like wooden doors etc..., and the DoorsMod.uax has modern sounds. Select the sound you want, then go to the Mover Properties and press the Use button of the fields to activate the sound.

Now, to choose sounds for your mover, keep this in mind:
-Use sounds with "start" or "S" in their name for the ClosingSound and OpeningSound. Use sounds with "end" or "E" in the name for ClosedSound and OpenedSound. Use sounds with "loop" or "L" in the name for the MoveAmbientSound. This way you get the best effect, because these sounds are made for this.
-Use sounds that belong together for the same mover. For example, use md6start, md6loop and md6end together. It is possible to use md4start, md5loop and md6end for 1 lift, but that sounds really weird.
-Never use looping sounds for the Closed-, Closing-, Opened- or OpeningSound, otherwise they will keep playing forever!

Choosing the sounds for a mover

If you ever have problems with the looping sounds, and there really is no explanation for it, try selecting another looping sound and after that back the original one, or if that doens't help, make the mover again. Sometimes this helps against mysterious problems.

Part II

Things you like to know

Many people wonder about these things but never tried it:

-Movers can go through walls. However the players standing on the movers cannot. Movers also work if you let them start in a wall, and if you place a mover completely away from your map, somewhere in the dark blackness, it will still move, although you can't see it. That will be useful if you are attaching things to a hidden mover.

-Movers work underwater. But you need to be aware that when a player stands on the mover, and the mover goes down, the player will stay floating on the water. The solution is to give the mover a roof and walls.

-When you save your map with movers without rebuilding, and reopen it later, all movers might disappear. At least, this happened to me once.

Rotating movers

You don't need any special mover class to make a mover that keeps rotating around its own axis forever. Any object, decoration, weapon, mover, etc... can be made to rotate, they all use the same propertie for it.

Make a mover. You don't have to give it any keys. Open its properties and expand "Movement". In there, expand "RotationRate". You now see three values: Pitch, Roll and Yaw. As long as you leave them 0, the mover will not rotate. Small values, like 1, 10 or 100 make it rotate very slowly, so you can hardly see the rotation. A value of 1000 makes it rotate quite slowly, and values of around 2000 - 10000 make it rotate faster. You can also make it rotate as fast as you want, for example if you give it a value of 100000, but at this high speed you might see strange effects when stepping on the mover.

The RotationRate of a mover

Use Pitch to make the mover rotate around its X-axis, Roll to make it rotate around its Y-axis and Yaw to make it rotate around its Z-axis. This means, if you want to make a rotating platform, you need to use Yaw, and for things like the wheels of a car, use Roll or Pitch.

The mover will rotate around its own axis. The location of this axis is determinated by that red vertex that every brush has. For example, the cylinder on the two pictures below will rotate around the red vertex, so the first one will rotate around its center, while the second one will rotate around one of its sides.

To place the red vertex, click on any purple vertex of the brush and the red one will go to that location, or right click on any place and select Pivot --> Place Pivot (Snapped) Here.

Important is to set the mover's InitialState to None, otherwise the movement of it will be disturbed when players touch it. Expand "Object" in the Mover Properties, and there set InitialState to None. I will talk about InitialState in a minute.

Triggered movers

All movers we made until now were activated by touching it. You can also make movers that are activated by triggers. First of all I will tell you how to make a trigger. Open the Actor Class Browser by selecting "Actor Class Browser..." in the View menu, or by pressing the pawn button [image] in the toolbar. In there, expand "Triggers" and there select "Trigger".

The Actor Class Browser

The trigger will be activated if a players walks in his radius. The trigger will then give an out event that will activate the mover, or anything else. Now place the trigger in your map, at a place where players can walk to activate it.

To make this trigger activate a mover, give the trigger an Event and give the mover the same Tag. Open the Trigger Properties and expand "Events". There, type a name under "Event" (Mover1 in my example). Now, open the properties of the mover that will be triggered, there expand "Events" too, and type the same name under "Tag" (Mover1).

The editor will now paint a red line from the trigger to the mover.

You also have to set the mover to be activated by a trigger, and not by a playerbump. Expand "Object" in the mover properties, and use InitialState for this.

The InitialStates of a mover

-None: the mover will never move through keys, but still can be used as a rotating mover or a mover attached to another one
-StandOpenTimed: Same as BumpOpenTimed
-BumpButton: The same as BumpOpenTimed, but the mover will return immediately
-BumpOpenTimed: the default setting. When you touch (bump) it it will go open, wait a while and then close again
-TriggerPound: This will be explained later
-TriggerControl: as long as the trigger is activated (as long as you are in its radius), the mover will be open. When you are not it the trigger's radius, the mover will be closed
-TriggerToggle: every time you enter the trigger's radius, the mover will toggle between open and closed
-TriggerOpenTimed: every time you enter the trigger's radius, the mover will open, wait a while and then close again

To make the mover work with a trigger, you will have to use one of the trigger settings, such as TriggerOpenTimed or TriggerToggle.

To determinate the radius of the trigger, open its properties and expand collision.

Choosing the radius of a trigger

The radius of the trigger is like a cylinder: use CollisionHeight to determinate the height of it, and use CollisionRadius to determinate the radius. As long as you stand in this cylinder, the mover is activated. If you want to view this cylinder in the 2D views, right click on top of the views, expand "Actor" and there choose "Radii View". You will have to do this.

Radii View

There are also some other trigger properties that might be interesting. In the Trigger Properties expand "Trigger"

The Trigger Proporties

The most important options are:
-bTriggerOnceOnly: If true, the trigger will work only one time, and after that never anymore.
-DamageThreshold: How many damage is at least required when TriggerType is TT_Shoot. The damage of the UT weapons is: (based on what's in the scripts and properties)
enforcer: 17
pulsegun: 72
shockrifle: projectile 55, shot 40, superexplosion 165
enhanced shockrifle: 1000
ripper: razorblade 30, explosive razorblade 34 (?)
biorifle: small glob 20, large glob 75
rocketlauncher: rocket 75, grenade 80
flackcannon: flakshell 70, chunk 16
redeemer: 1000
So a trigger with DamageThreshold = 999 will be activated by the redeemer, but if DamageThreshold = 1001 it will not
-Message: A message that will appear in the textbox of your HUD when you enter the trigger's radius
-RepeatTriggerTime: If the mover has a message, this determinates after how many seconds the message will be repeated as long as you are in the mover's radius. 0 means the message will be displayed only once without being repeated.
-ReTriggerDelay: If this is larger than 0, you will only be able to activate the trigger again after the TriggerDelay time is expired.
-TriggerType: determinates what will activate the trigger:
TT_PlayerProximity: the trigger will be activated if a player is in its radius
TT_PawnProximity: it will be activated when a pawn is in its radius
TT_ClassProximity: it will be activated if the Class you selected in ClassProximityType is in its radius. This might not work.
TT_AnyProximity: it will be activated if a player or a pawn is in its radius
TT_Shoot: it will be activated it you shoot at it, and the damage is larger than what you entered in DamagaThreshold.

Movers & lighting

Movers have several properties that have to do with lighting: expand "Mover" in the Mover Properties.

-bDynamicLightMover: If True, the lighting will be calculated for every place where the mover will be, so if its first in a dark room and goes to a bright one, the mover will become bright as well. Don't use these too much if you want your map to work on slower computers.
-BrushRaytraceKey: If the mover isn't a dynamiclightmover, the lighting on the brush will be calculated for this Mover Keyframe only.
-WorldRaytraceKey: If the mover isn't a dynamiclightmover, the lighting around the mover (for example shadow of it) will be calculated for this Mover Keyframe only.

An example of the effect of WorldRaytraceKey is shown on these screenshots. The mover is a lift with two keyframes: Key0 is down, and Key1 is up. Of course this only works when bDynamicLightMover is False

WorldRaytraceKey = 0

WorldRaytraceKey = 1

The second shadow is calculated as if the mover was at its up position. You can also use this to create fake shadows.

Looping Movers

Looping movers are movers that, once activated, will keep moving forever. There are a lot of ways to make a looping mover, I will explain three of them. Every way has it own advantages, disadvantages and results.

The DualDispatcherMethod (Thanks to Wanderer): This method needs two dispatchers and a trigger. Once you activate the trigger, one of the dispatchers will start a chain-reaction that makes a normal mover toggle between its keyframes.

In your map, first add a normal mover, give it the Keys you want, and open its properties. Set its InitialState (under "Object") to TriggerToggle. Also give it a tag (under "Events"), for example "loopingmover".
Now add two dispatchers (they are in the Actor Class Browser under Triggers).

Open the properties of the first one, and expand Events. Give it a Tag, for example "Dispatcher1". Now, expand "Dispatcher" and there expand "OutEvents". Set [0] to the tag of the mover, in this case "loopingmover", and set [1] to "dispatcher2". After that, expand "OutDelays" and set [1] to the time the mover needs to move from its first key to open or close (in seconds). So if the MoveTime of the mover is 2, but it has 4 keys, it will need 6 seconds to move. (not 8 seconds! 4 keys means it has to move from Key0 to Key1, then from Key1 to Key2, and then from Key2 to Key3, which is the last key).

Now do the same for the second dispatcher, but only give this one "dispatcher2" as tag, and set its OutEvent [1] to "dispatcher1".

You now have to do only one more thing: add a trigger somewhere in the map. When you open the map in UT the mover will not yet move, first one of the dispatchers needs to be triggered and after that the mover will keep moving forever. If you want it to appear that the mover was moving already, place the trigger somewhere nearby a startlocation so the player will activate it without even knowing it.

When you placed the trigger, open its properties and set its Event under Events to "dispatcher1" or "dispatcher2", you may choose which one yourself.

The LoopMover: There are different kinds of movers. To get a list of all movers, right click on the Add Mover Brush button instead of left clicking on it. "Mover" is the one we used until now. However, now choose "LoopMover" instead.

The Mover Classes

After you added it and made its Keys, open the LoopMover Properties. Expand "Object" and then "InitialState". As you can see there is a new propertie there, "LoopMove". This is the only InitialState that makes the LoopMover work. Select it.

The LoopMove InitialState of the LoopMover

The LoopMover will not move on its own. It will need a trigger. Add a trigger somewhere, give the trigger an Event and the LoopMover the same Tag. If you now play the map, the LoopMover will start moving as long as you are in the radius of the trigger. If you step out of the radius, the mover will stop at the next key it will reach.

If you want the mover to keep moving, even if you are not in the radius of the trigger, it's best to use a TimedTrigger (Thank you, 32_Pistoleta, for pointing me out the NaliRabbit wasn't necessary :)
The TimedTrigger in the Actor Class Browser --> Triggers --> Trigger --> TimedTrigger. Open "TimedTrigger" in it's properties and set bRepeating to True. In DelaySeconds, enter the total time the LoopMover needs for 1 cycle (opening and closing). If you don't do this, this trigger will not work in Tournament-style maps (where you have to press a button before the map starts). Of couse don't forget to set the Event of the trigger to the tag of the LoopMover.

If you experience any problems with the TimedTrigger, or you are using Unreal1, you will need the NaliRabbit anyway. For this, I am making a tutorial: "Activating a trigger with a NaliRabbit"

One final thing you can do is set the LoopMover's MoverEncroachType to ME_IgnoreWhenEncroach, otherwise its movement will stop forever when it hits a player.

If you want to prevent that problem, you can also use the DualDispatcherMethod in combination with a LoopMover. Set OutDelay [1] to the MoveTime of the mover then, instead of the total time it needs to move.

Now, what is the difference between the DualDispatcherMethod and the method with the LoopMover? its in the sequence of the Keys the mover will follow, if there are more than two keys: For example, if the mover has three keys, a normal mover will move from Key0 to Key1 to Key2, then it will go back to Key1 and then back to Key0.

A LoopMover, however, will move from Key0 to Key1 to Key2, and then immidiatly the shortest way back to Key0.

So what method you use depends on how you want your looping mover to move.

TriggerPound: This method uses a particular InitialState of a normal mover: TriggerPound. So when you added your mover and gave it some keys, set its InitialState to this. TriggerPound is somewhat the same as the LoopMove InitialState of the LoopMover, only TriggerPound will use the same key sequence as the DualDispatcherMethod. So to activate the mover you have to do the same as you did with the LoopMover.

The advantage of TriggerPound is that you control 2 different timers: how long the mover will wait at the last key before closing, and how long it will wait at the first key before opening again. In the Mover Properties, expand Mover. To set how long it will wait at the first key, use StayOpenTime. To set how long it will wait at the last key, use OtherTime.

You can represent it like this:

AttachMovers

There is a special AttachMover class, but actually its easier and more reliable to use normal movers if you want an object to move together with a mover.

Make a working normal mover, and give it a Tag, for example "AttachMover". Now add some objects, for example weapons, decorations, lights, etc... in the map. Open the properties of the objects, and expand "Movement". In there, set the AttachTag to the same Tag you gave the mover, in this case "AttachMover". Now expand "Advanced" and make sure that bMovable is True, bNoDelete is False and bStatic is False.

The Properties for a moving object

The object will now always make the same movements as the mover, no matter how far it is away from it, and even if the object has to go through walls.

You can also use the AttachMover class. Right click on the Add Mover button to see it. After you added one, open its properties and expand "AttachMover". There give it an AttachTag. Now, all objects with the same Tag will move together with it.

So, the difference between using normal movers, and using AttachMovers, is that with the normal mover, you need to give the objects an AttachTag, and the mover the same Tag, and with AttachMovers, you have to give the objects a Tag and the AttachMover the same AttachTag.

Attaching movers to another mover

It is possible to attach another mover to a mover, just the same way as you attach an object to it. This way, you can make movers that have more states than only open or closed. If you have a mover (A) that is attached to another one (B), mover A will move if it is activated by bumping or a trigger, but it will also move if mover B moves. If mover B moves in a different way than mover A, mover A is able to move through two different paths: its own one, and the one of mover B.

Of course you need to hide mover B somewhere in your map, players want to see mover A only!

If you want the mover to be attached to more movers, you will have to create a chain: mover A attached to mover B, and at the same time mover B attached to mover C.

There are some problems with this: when a mover is attached to another one, and also has it's own keys, the following scenario might happen: Mover A moves to the left. Then Mover B moves up, and Mover A will follow Mover B and also go up. Now mover A is up and to the left. If Mover A now wants to move to the right again, it will move to the Key that represents the right position, so it will automaticly down again, even if Mover B stays up. If now Mover B moves down, Mover A will also move even more down, so it will disappear in the floor!

One of the main things you can do when attaching a mover to another mover, is make a lift with inner doors. So the doors will descend and raise together with the lift.

Rotations might not work, however I have seen it working sometimes.

If you start using this, you will see that attaching movers to other movers has great potential, you can do amazing things with it without having to script!

Mover events

There are several events a mover can give when something happens with it.

The first kind of event, is when something or someone bumps it. Under "Mover" in the Mover Properties are two settings: BumpEvent and PlayerBumpEvent. BumpEvent will be activated everytime a player or an object bumps the mover, and PlayerBumpEvent will be activated only when a player bumps it.

The second kind of event is the same event you use for triggers: its under "Events" in the Mover Properties. When you enter the name of an event in Event, that event will be called when the mover has reached its last keypoint. This way you can for example make a button that is a small mover that moves into the wall, and as soon as its there a door opens. You don't have to use any trigger for this.

Some types of movers, such as the GradualMover and the AssertMover can give a different event for every Key they reach. I'll handle this later.

The ElevatorMover

One of my favourite mover classes is the ElevatorMover. That's because this mover gives you control over each key. For example if it has 4 keys, you can place 4 ElevatorTriggers in the map: one to go to Key0, one for Key1, one for Key2 and one for Key3.

To add an ElevatorMover, right click on the add mover button and choose ElevatorMover. Now give it 4 different keys.

Open the properties of the ElevatorMover, expand Object and set InitialState to "ElevatorTriggerGradual". After this expand Events and set the tag to "ElevatorMover".

The ElevatorMover does not work with normal triggers. You need to use ElevatorTriggers. These have some specific properties, that a normal trigger hasn't got. You can find the ElevatorTrigger in the Actor Class Browser under Triggers.

The ElevatorTrigger

Add four of these triggers in your map (one for each key), and open their properties. Under "Events", set their Event to "ElevatorMover". You now should see red lines going from the triggers to the mover.

4 ElevatorTriggers, one for each Key of the mover

After this, select one of the ElevatorTriggers, open its properties and expand "ElevatorTrigger".

The ElevatorTrigger Properties

It has the following properties:

-bTriggerOnceOnly: the trigger will work only once, and then it will never work anymore.
-ClassProximityType: used together with TT_ClassProximity. Go to the section "Triggered Movers" for this.
-GotoKeyFrame: this is the setting that makes the ElevatorTrigger unique: when you activate an ElevatorTrigger, it will not only give the command to the mover to start moving, but it will also tell the mover to which key it has to move, and that key do you control by using this setting.
-MoveTime: if it is larger that 0, this should determinate the speed of the ElevatorMover, but I have never seen this work. If you get it to work, please contact me.
-TriggerType: What will activate the trigger. Go to the section "Triggered Movers" for this.

Set "GotoKeyFrame" for each of the 4 triggers to respectively 0,1,2 and 3.

If you now play this map, and you walk in the radius of one of the triggers, the mover will go to the Key that you selected in GotoKeyFrame of the trigger, and stop there. It does not matter where the mover starts, it will always reach the correct keyframe!

This kind of mover is called "ElevatorMover", but it can be used for other things as well, of course. Anything that needs multiple fixed positions will need one. A good example is a train with a button on each stop position of it to call the train. Also if you want to make a mover with only two Keys, but a separate trigger for each key, you need to use this.

The sounds of the ElevatorMover don't work as supposed; never use looping sounds for this mover, or they will stay playing forever.

There is also another bug: when the elevator is encroached, it will stop and never listen to any of the buttons again. The only solution is to set MoverEncroachType to ME_IgnoreWhenEncroach.

The AssertMover

This mover will keep opening as long as you are in the trigger's radius. When you step out, it will wait at the first keyframe it reaches on its path, and then return. This means the longer you are in the trigger's radius, the more the mover will open, providing it has more than 2 keys.

To add one, right click on the Add Mover button and select AssertMover. Give it more than 2 keys, for example 4. Set its InitialState to "AssertTriggerOpenTimed". Give it a Tag, for example "AssertMover", and add a trigger with the same Event.

Then expand "AssertMover" in its properties, and use the following parameters:

The AssertMover Properties

-bOnceOnlyStopOpen: if this is True, the mover will stay at its last keyframe forever once it has reached it.
-CloseTimes: The normal mover has only one MoveTime setting, that determinates the movespeed between every two keyframes. But the AssertMover has a separate setting for each keyframe. CloseTime[0] is the time the mover needs to close from Key1 to Key0, CloseTime[1] is the time it needs to close from Key2 to Key1, etc... Never forget to use these instead of the MoveTime setting. If you leave these at 0, your mover will move unrealistically fast.
-OpenTimes: OpenTime[0] is the time it needs to open from Key0 to Key1, OpenTime[1] is the time it needs to open from Key1 to Key2, etc...
Too bad, Close- and OpenTimes will only work when the InitialState is "AssertTriggerOpenTimed". If you use any of the other InitialStates, the MoveTime will be used. If you really want a bumpmover to have different Close- and OpenTimes, you can simulate one by attaching the trigger to the mover (see section AttachMovers for this).
-WaitUnAssertTime: this is the time the mover will wait before returning when you left the trigger's radius.

The GradualMover

The GradualMover changes its Tag at every keyframe. So it its at Key0 it will listen to another trigger than when its at Key1. You can also set an Event for each key, so the mover will call another Event everytime it reached one of its keys. Add one and open its GradualProperties.

The GradualMover Properties

-CloseTimes: this is the same as the CloseTimes of the AssertMover
-Events: the events the mover will call for its first 6 keys. You can use this for example to open a different door everytime the GradualMover is at another floor.
-OpenTimes: this is the same as the OpenTimes of the AssertMover
-Tags: the tags of the mover for its first 6 keys. If Tag[0] is "A" and Tag[1] is "B", and the mover is at Key0, the mover will move if it receives an event "A", but not if it receives an event "B". If its at Key1, it will only by activated by event "B" and not by event "A".

If you go to its InitialState propertie in Object, you will note that there are 3 new InitialStates:

-GradualTriggerToggle: when activated by the trigger for Tag[0] the mover will go to the last keyframe, and return to the first keyframe when triggered again by that same trigger. The mover does not stop at the middle keyframes, and you can't use the different tags, only Tag[0] will be used. The different Events work, of course.

-GradualTriggerPound: this makes the mover go a little weird. When I tested it looked most like this: when you enter the trigger's radius for the first time, it will open and then close. When you leave the radius it will open and close again. But when you enter the trigger again, it will suddenly act like a GradualTriggerOpenTimed mover, which is described below. The trigger I mentioned was Trigger0 of the example below.

-GradualTriggerOpenTimed: this is the only InitialState that fully uses the different tags. If the mover is closed, and if Tag[0] is "A", Tag[1] is "B" and Tag[2] is "C", and the corresponding triggers have the same events, Trigger0 will make the mover go to Key1. It will wait there forever, until you activate Trigger1. Then the mover will go to Key2. This is the last key in this example, so now the mover will wait for StayOpenTime and then go back to Key0. If you use 6 different keys, you will have a mover that will only reach its last key after you activated 5 triggers in the correct order (the last key doesn't need a trigger). Plus you can use the different Events of the mover to activate other things.

ReturnGroup

Quite important, but not known by a lot of people, is the ReturnGroup setting for movers. It is used to divide movers with the same Tag into subgroups.

If you encroach a mover (= block its path), it will stop or return (or crush or ignore you, but that's not important in this section), depending on its MoverEncroachType. If you have different several movers with the same Tag, and you encroach one of them, the other movers will stop or return as well! If you don't want this to happen, the only thing you have to do is give each mover a different ReturnGroup. Now your two movers have still the same Tag (activated by the same trigger etc...), but will not return or stop together when encroached.

Warning: when you add movers, no matter how many, the Tag of all of them will be by default "Mover", this means all movers have the same Tag if you don't give them another one yourself. If you ever had doors acting strange when encroaching an elevator in your map, and wondered why, this is the reason. To avoid this give them different Tags or give them different ReturnGroups.

Some mover classes, like the GradualMover will also return or stop together if they have different Tags. You always have to give them different ReturnGroups if you don't want this. If you have made a puzzle using gradualmovers, the puzzle can be ruined if you don't give them a different ReturnGroup!

If you have normal movers with different Tags but the same ReturnGroup, they will also stop or return together.

More Mover Properties

This lists all the mover properties that weren't explained yet in the other sections.

-bDamageTriggered: the mover will be triggered if it gets the damage amount defined by DamageThreshold. This only works if the InitialState of the mover is TriggerOpenTimed or TriggerToggle. For a list of the damage of the UT weapons, and more about InitialState, go to the section Triggered Movers.
-bSlave: makes the mover brush a slave of another mover with the same Tag. This is another way to attach movers to each other, and the effect is the same as if you would use the AttachTag of a mover.
-bUseTriggered: this was supposed to activate the mover when a player pushed a key on the keyboard, like the use key in HalfLife. This was left away in the final version of Unreal.
-DamageThreshold: The amount of damage the mover needs to get to be opened when it is bDamageTriggered.

Part III

A door that opens by pushing a button

This will be a regular door, that is opened by a button. The button itself is also a mover that disappears in the wall when you push it, and returns after a few seconds. There will not be used any triggers.

First make two rooms and connect them with a door. Set the InitialState of the door to TriggerToggle or TriggerOpenTime, and set its Tag to "Door". Now add a mover that looks like a button next to the door. Make Key0 the position of the button outside the wall, and Key1 the position of the button inside the wall. Set its Event to "Door". You can also use BumpEvent instead, then the door will open as soon as you touch the button, instead of after its completely in the wall. You should see a red line going from the button to the door.

Now make a similar button for the other room (otherwise you will not be able to open the door again when you're in the other room).

That's it, its done!

The door with buttons

A train with a button

This train will have one button in it to toggle between two stations. In the stations will be placed a button as well to call the train.

Make a large area and make tracks. Then make a mover that looks like a train with a button in it, and let it be able to go to both stations.

The train mover

Set the train's InitialState to TriggerToggle and Tag to Train. Add a trigger in the train, set both its AttachTag and Event to Train. The trigger will now move when the train moves, so it will always follow the train. Sometimes this might give small problems, especially if you give the trigger a small radius. So give the trigger a large radius. If you would have placed two fixed triggers at the begin- and endposition of the train, you would reactivate the triggers everytime you reach the other side, so attaching it is the only solution.

Now also add two buttons with triggers in the stations, and set their Event to Train as well (but not their AttachTag!)

The triggers for the train

The buttons will call the train immediately, even if its moving. This might be annoying in multiplayer, where players will be pressing the buttons on two sides at the same time while another player is on the train, etc... To prevent this you can remove the triggers in the stations, or you can use an ElevatorMover for the train instead, and give it two buttons. ElevatorMovers don't listen to triggers while moving. The only disadvantage then is that you won't be able to give your train sound.

An example map, dm-train.unr, is included in the zipped version.

A wiggling boat

In reality, boats always wiggle a bit with the waves. That's a good reason to make your boats or rafts in UT do this as well.

To do it, attach the boat to another mover that does the wave movement. The keys of the boat itself are the different places it will sail to.

Rotations will not work for attached movers, but you still can make a subtle up and down movement. Actually, I'm not sure if rotations work or not. When I tried it, it didn't, but once I attached a mover to a bird, and the mover rotated when the bird did.

Here's a step-by-step guide on making such a boat:

Make a room or outdoor environment with water in it, and place boat or raft on the water.

The raft

Give the raft a Key1: its position on the other side of the water. Now you have a working normal raft.

Now make a new room outside your map, with a TimedTrigger and a mover inside of it. Set the movers InitialState to TriggerPound, set StayOpenTime and OtherTime to 0.5 and its MoveTime to 1. Make its Key1 a little below Key0 (8 or 16 units lower). Read the section Looping Movers to get this to work.

Give the trigger the Event "Wiggle", give the small mover the same Tag, and give the boat mover the same AttachTag.

If everything went well, it should work now. If you play the map you will find the raft is moving up and down on the waves. It will only move up and down when it's not moving to the other side of the water. You can't do much about that (except if you give the raft more keys), its the way the movers are programmed.

An example map, dm-boat.unr, is included in the zipped version.

A Real "Office Building" Elevator

I made a seperate page on this: elevator.html

Go to http://www.planetunreal.com/lode/ for more tutorials

Download

The example maps are included

movers.zip

The Future

I WILL update this tutorial

If you have any ideas, problems, suggestions, questions or have discovered a mistake, don't hesitate to contact me! Thanks a lot.

Contact

My email adress is hybrid6666@yahoo.com

(c)2000-2001 Lode Vandevenne

Please do not upload this tutorial to any site, only make a link to http://www.planetunreal.com/lode/ Otherwise older versions keep hanging around on the net.


A real "Office Building" Elevator

A Real "Office Building" Elevator v1.0

By : Lode Vandevenne

lode@altern.org

Lode's Unreal

Welcome to the first tutorial explaining how to make such an elevator with working inner doors!!

I suggest you read Lode's All about Movers Tutorial first, as this tutorial is based on the knowledge in that one.

We are now going to make a real elevator with a realistic liftcage, inner doors that are attached to it, outer doors on each of the 4 floors, 4 buttons inside the lift and one button on each floor.

Subtract 4 floors 256*1024*1024 (H*W*B), leaving 128 units between each floor. Now subtract a 1408*256*256 shaft on the left or right side of the room, 32 units away from the rooms. Now subtract 4 doors from each room to the shaft. It should now look like this:

After this make a new 1024*1024*1024 room to make the template of the lift. To make the liftcage use a 256*256*256 brush and subtract a 240*240*240 brush out of it. Place four buttons on the wall of it and give them numbers as texture (1,2,3 and 4). There are some numbers in the Starship.utx package. Also, set all its textures to Bright corners, otherwise there might occur some lighting problems. Intersect the whole thing.

Now place the red brush on the ground level in the shaft, and add an ElevatorMover. Now give it 4 keys: one for each floor. On the following screenshot you can see the 4 keys of the mover.

Open the properties of the ElevatorMover, expand Object and set its InitialState to ElevatorTriggerGradual. Set its Tag to ElevatorMover.

Now add 4 ElevatorTriggers, inside the lift: one for each button. Set the AttachTag of the ElevatorTriggers to "ElevatorMover", so they will move together with the lift. Make their CollisionRadius small enough, for example 25, so you can't press 2 buttons at the same time. Use Radii View to see the radius of the triggers. Set the Event of all the triggers to "ElevatorMover", and set the GotoKeyFrame of the triggers to respectively 0,1,2 and 3.

Now add a button on each floor next to the door to the shaft. Duplicate the four ElevatorTriggers you added, and place one on each floor. Of course, use the correct one for the correct floor, for example place the one with GotoKeyFrame = 0 on the lowest floor. Also, clear the AttachTag of these movers, because they need to stay on their place.

Now the lift can already move to each floor, and has buttons inside and outside. Now here comes the hard part: the double inner doors. The doors need to separate movers, and they have to be able to move up/down together with the lift, and they also need to be able to open and close on each floor.

There is only one way to get this to work: make the doors to be ElevatorMover as well, so they can move up/down together with the lift, and for the open/close movement of the doors use two other movers, and attach the doors to these.

Now make a door brush, I made it with a little window in it, and place it inside the cage on the location you can see on the screenshot below, and add it as and ElevatorMover. Now add in again on the other side, so it will be double doors. Give the doors the same keys as the lift and set their initialstate to ElevatorTriggerGradual. Give both doors the same Tag: "idoors".

Also, duplicate ALL the ElevatorTriggers, place them on EXACTLY the same spot as the old ones, and set the Event of all the new ones to "idoors". (the quickest way to do this is right click on one ElevatorTrigger, choose select all ElevatorTriggers, then right click on one and select "Duplicate". Now all the new ones are selected. Open the properties of all of them at the same time and set the Event. Then move them all to the same position as the old ones.) This way the doors will be able to move up and down together with the lift.

Now, add two doors behind the lift, on a place where nobody can see them. You can place them in the black emptiness outside the rooms, they will still work there.

Set their Key1 like this, and then set them back to Key0:

Now give one of them the Tag "idoor1" and the other one the Tag "idoor2". Set their InitialState to TriggerControl. Now, add 2 triggers on each floor, on this spot:

So that makes a total of 8 triggers. On each floor give one of them the Event "idoor1" and the other one the Event "idoor2".

Finally, select one of the liftdoors that are in the lift, and set its AttachTag to its corresponding idoor: idoor1 or idoor2. Do the same for the other liftdoor.

For the outer doors: you have to add them to each floor. You will have to use a total of 8 doormovers: two on each floor. Give the ones on the lowest floor the tag "odoor1", the one on the next floor "odoor2", etc... and set their InitialState to TriggerControl. Add 1 trigger on each floor, at the same location as the triggers for the innerdoors. Give the new triggers the correct event for the outer doors of its floor.

Now your lift will look somewhat like this:

If you did everything well, your map should now have:

-3 ElevatorMovers
-10 regular Movers
-16 ElevatorTriggers
-12 regular Triggers

and all this just to make one Real "Office Building" Elevator!

You can rebuild, save and play your map now.

An example map, dm-elevator.unr, is included in the zipped version.

Contact

Contact me through email: hybrid6666@yahoo.com or ICQ: 73177230

(c)2000-2001 Lode Vandevenne

Please do not upload this tutorial to any site, only make a link to http://www.planetunreal.com/lode/ . Otherwise older versions keep hanging around on the net.


Movers That Are Triggered By Keys

By: IceLord (NL)

icelord_nl@hotmail.com

Editor used: Unrealed2.0 Download .zip

We all know Doom and Quake, right? In that case, you can definitely remember searching for the right key to open that &^%*#@door at the end of the hall at level 7, right? (This is just an example, don't mail me because there is no door at level 7 in Quake )

In Unreal there are only Movers that can activated by bumping into them, shooting at them or by activating them with an event (as far as I know). But at www.planetunreal.com/chimeric I found some very interesting stuff.

Before moving on to the actual tutorial I'd like to thank "i thought i saw a crack_addict" for his scripting talent (boy, I really need to take some scripting lessons…I can't keep going on borrowing scripts from others and making tuts out of them)

The concept of the KeyMover:

To explain the concept of the KeyMover I have provided an example map. In this example map you can only open the door when you are in possession of the flashlight (it doesn't make any sense, but it works ).

- Copy the example map to your \UnrealTournament\Maps directory and startup UT.

- Start a Practice Session, set the GameType to Tournament DeathMatch, select DM-KeyMoverExample as your map, set the number of bots to 0, and click on Start…

As you have seen: no flashlight, no entry. But if you do have the flashlight, the door will open when it is bumped.

The concept of the KeyMover is pretty simple, all I needed in this example is:

  • One KeyMover (SpecificKey = Class'UnrealShare.Flashlight')

  • One "Key" (the flashlight) (Tag is irrelevant, Event = None)

The KeyMover works like this:

The KeyMover is an ordinary Mover, except that it needs a specific key to be opened. When a player or bot is touching the KeyMover, it searches in their inventory whether or not it contains (a copy of) the specific key (in our case the flashlight). If it does, the KeyMover will move (open). If the player or bot is not in possession of the specific key, the KeyMover will stay closed (won't open).

The KeyMover:

Before we can add any KeyMovers to our level, we first have to do some scripting.

Lucky us, the scripting has already been done by someone else. I have only changed some minor things (like removing the comments), so I can't take any credit. All the credit goes to "i thought i saw a crack_addict" and the guys at www.planetunreal.com/chimeric

(For the original script see the HTML -document)

Back to the tutorial:

Just follow me:

1. Startup UnrealED 2.0

2. Open up the Actor Class Browser > Brush > Mover

3. Right click mouse New…

4. Package: MyLevel

Name: KeyMover

5. Copy the following lines into the script (overwriting all the text there is):

// =============================================

// KeyMover

// =============================================

class KeyMover expands Mover;

var() class SpecificKey;

state() BumpOpenTimed

{

function Bump(actor Other)

{

local Inventory key;

BroadcastMessage(Other.Name$" is trying to open the door!!!");

if (Other.IsA('Pawn') && SpecificKey != NONE)

{

BroadcastMessage("Searching for "$SpecificKey);

Key = Pawn(Other).FindInventoryType(SpecificKey);

if (Key != NONE)

{

Broadcastmessage("Found the key!!!");

Super.Bump(Other);

}

else BroadcastMessage("Couldn't find key!!!");

}

}

}

6. Compile the script with hitting F7

7. Close the script

8. In the Actor Class Browser click on View and select Show Packages

9. Select MyLevel and click on Save Pkgs.

If you don't want all those messages appearing in your game, you can edit this script and remove all the lines which contains "BroadcastMessage" or, even better, write "//" before each line that contains "BroadcastMessage" (so these lines will become comments (green), and will be ignored when compiling the script).

That's all for the scripting part.

Now we can add a KeyMover to our level, just like a RotatingMover or ElevatorMover, by right-clicking on the add-mover-button and selecting KeyMover.

The rest:

Thus: instead of adding a normal Mover as your door/lift, add a KeyMover to your level.

Then add the key (in our case the flashlight) to your level.

Then open up the properties of your KeyMover. Goto KeyMover SpecificKey, and click on [Use]

Setup the KeyFrames and make sure that the KeyMover is BumpOpenTimed.

Add sounds

Test level…

Good luck,

IceLord (NL)

If you rebuild now you will notice that you cannot see the clouds we put in the sky box. That is because we currently have no lighting! Well let us put some lights in the skybox. Right click on the cloud texture we just added in the sky box and select Add Light Here. You should now be able to see the clouds:

Pop-quiz:

Question: Why do we immediately edit the KeyMover's properties after the required key is added to our level? (see below)

Important notes:

The KeyMover searches your inventory, so setting up a decoration-object (like a book) as your key is of no use. If you do want to have "real" keys, you'll have to make them yourself.

Answer: Simple, because now the key is still "active" in your Actor Class Browser. With a simple click on [Use], your key is specified as the required key to open the door. Otherwise you would have to click on […] and manually search for your key in the Actor Class Browser. It just saves you some time, that's all.


BB Drac - Unreal Tournament UED2 guide Movers explained

Movers Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Movers play an important part of UT.
This is what you need to use when creating doors, elevators
and most moving objects in this game.

A mover is basically a regular brush, added as a mover, but have
additional moving properties.
How they should be activated, like touch, trigger, looping or by other
types.
When moving a mover use keypoints as targets when moving from
one position to another.
This is known as keyframes and they are just different positions
of the mover brush.

To create a mover you either create a brush like any normal brush
or a complex one, still the same way as a normal complex brush.
(Check my complex brush tutorial for more information).
When the brush is done you place the brush where the mover is to be
and then press the "Add mover" button.
A purple framed brush should appear.
That is the mover, but as it is nothing will happen.

Mover problems that have been reported is when the mover
do not seem to block players or have a collision with actors that
are somewhat weird.
This is a scaling problem as the movers true collision size get
all screwed up.
To avoid this problem reset the brush scaling before adding a mover.

Here is a list of properties you might take a closer look at:

Property | Specific
+Mover |
bDamageTriggered | Damage infilicted on the mover is needed to trigger it.
bDynamicLightMover | Lighting is calculated for each keyframe of the mover.
BrushRaytracekey | Add lightning to the mover as if it was in the specified keyframe.
bTriggerOnlyOnce | Mover will turn inactive once triggered.
BumpEvent | Event to happen if mover is bumped when state is BumpOpenTimed.
BumpType | What type of class that can trigger the mover.
DamageThreshold | Amount of dmg needed to trigger the mover if bDamageTriggered.
DelayTime | Time before mover actually starts to move when triggered.
EncroachDamage | Amount of damage inflicted upon players if hit by the mover.
KeyNum | Current mover keyframe and at start of game.
MoverEncroachType | Mover reaction when hitting a player.
MoverGlideType | Mover accelerates or move with constant speed.
MoveTime | Time used by the mover to move between two keyframes.
NumKeys | The amount of keyframes the mover moves through.
OtherTime | Time delay between open and closed when state is TriggerPound
PlayerBump | Event to happen if bumped by player when state BumpOpenTimed.
StayOpenTimed | Delay to wait before mover returns to orginal state.
WorldRaytraceKey | Add lightning to the world as if it was in the specified keyframe.
+MoverSounds |
ClosedSound | Sound heard when mover has finished closing.
ClosingSound | Sound heard when mover starts to close.
MoveAmbientSound | Sound heard while moving, either opening or closing.
OpenedSound | Sound heard when mover has finished opening.
OpeningSound | Sound heard when mover starts to open.
EncroachType | Specific
Stop | Mover halts and will not be activated again.
Return | Mover returns to its last state (open or closed).
Crush | Instantly kills the player/actor.
Ignore | Mover actually moves straight through players/actors.

Under Object you have Inital State.
This is how the mover is triggered.

Initial State | Specific
None | Nothing will trigger this mover (Inactive).
StandOpenTimed | Moves through its keyframes and then returns to orginal state.
BumpButton | Don't know how this works.
BumpOpenTimed | Moves through its keyframes and then returns to orginal state.
TriggerPound | Mover moves repeatedly as long as player triggers the mover.
TriggerControl | Mover will move as long as player stays in trigger radius.
TriggerToggle | Mover change between open and close state when triggered.
TriggerOpenTimed | Like bump/stand open timed but with a trigger.

Open/Close and moving:
The term Open and Close when referring to a mover is to make
things a bit easier.
Open is referred to when the mover is moving from one keyframe to
the next in line. Like 0 through 7.
Close is used when the mover moves back to the base position again.
Keyframe 7 back to 0.

Changing the keyframe and mover position:
To make a mover move you need to position the mover where
you want it to move in the different keyframes.
Press the right mousebutton on the mover and select "Movers" and then
the appropriate key 0-7. Move the mover to the position you want it to
move to.
The current keyframe you have selected will show under "KeyNum" in the
mover properies and will also be the key frame the mover starts in.

When the mover is activated it will cycle through all its keyframes
(0-7) and then return to its original keyframe/position.
The amount of keyframes it will cycle through is specified with the
"NumKeys" property.

 Changing the movers texture:
If you want to change the textures on the mover you need to
recreate it and add a new mover.

If you have patch 4.36 installed you don't need to do that.
Press the right mousebutton on the mover and select "Movers" and then
"Show polys" and the mover textures will show and allow you to change them.

 StandOpenTimed or BumpOpenTimed:
If you create simple touch triggered movers you should use either
StandOpenTimed or BumpOpenTimed.
If you create an elevator you must use StandOpenTimed and
BumpOpenTimed for others, like doors, if you want the best
support for bots.
They treat BumpOpenTimed movers as doors and StandOpenTimed as elevators.

 Mover, into walls or not:
As far as I know there is no problem for a mover to move into solid
walls.
However, a mover is solid and so is the wall which makes it theoretically
impossible.
Both ways of dealing with this, creating openings for the mover and not,
are used widely.

In some situations things might look weird if players are able to see that the mover
actually move into a solid wall.

My tutorials deal in almost all cases with movers that have space created for them
to move to/inside (breakable glass/walls do not).

 Different mover types:
If you press the right mousebutton on the "Add mover" button
you get a list of movers you can add.

Movers | Specific
Mover | This is the default mover type.
AttachMover | Allows actors to move along with the mover.
AssertMover | Mover that will keep opening as long as trigger is active.
RotatingMover | Like a normal mover but have a default rotation rate.
ElevatorMover | Allows the usage of elevator triggers.
MixMover | A combination of Elevator, Attach and Gradual mover.
GradualMover | Will move a keyframe by different triggers.
LoopMover | Keeps looping through its keyframes until it's not triggered.

Mover
This is a normal mover.

 Attach Mover
The attach mover is used to make objects move along with the
mover when activated.
Under the property "AttachMover" you have "AttachTag".
All items that has the same tag as this "AttachTag" will be
affected by the mover.
Note that the object(s) need to be movable for this
to work, so change the bMovable to True, bStasic to False and.
bNoDelete to False. (All under Advanced on the object).
Lights may not work entirely as you want so testing might be needed.

Actually you don't need to have attach mover to make objects "stick".
Under the property "Movement" on the object you have "AttachTag". Just change this
to the same as the Tag on the mover and you have the same effect.

 Assert Mover
This mover will move through its keyframes as long as the trigger
is active (player in trigger radius).
When no longer true the mover will stop and move back to base position.
bOnceOnlyStopOpen - The mover will stay at its last keyframe if true,
when it reach that keyframe, otherwise it will return.
CloseTimes[X] - Time mover use in the close movement.
OpenTimes[X] - Time mover use in the open movement.
WaitUnAssertTime - Timedelay when trigger is no longer active
before the mover starts closing.

(I haven't been able to get this mover to work 100% and especially
if the bTriggerOnce is false).

 Rotating Mover
The rotation mover have one extra property set which is "RotationRate".
By adjusting the value you set a default rotation speed of the mover
which it will have at all times.

This is kind of useless, unless I missed something, considering that
all objects already have the "RotationRate" property set, located under
"Movement" that do and act the exact same way.
The only difference is that you need to set "FixedRotation" true.

The speed you set can be negative or positive, one for each direction.
500 is pretty slow and 5000 normal.
Pitch means movement up and downwards, Yaw movement sideways (left/right)
while Roll rolls sideways, left or right.

When the mover rotates it rotates "out" of keyframe meaning that
if it is activated/triggered it will rotate back to frame and then
keep on rotating, which could produce some weird behavior.
This also applies to EncroachType. Best is probably "IgnoreWhenEncroach".

 Elevator Mover
The Elevator mover allows a better control of elevators movement.
By adding a ElevatorTrigger you can specify which keyframe
the mover goes to.
The Event under the Elevator trigger must be the same as the elevator
tag and the property GotoKeyframe which keyframe the mover moves to.
(More info on the elevator trigger in trigger tutorial).

 Mix Mover
This is a combination of Attach, Gradual and Elevator mover.
I have seen somewhere that even though this is part elevator mover
it do not support elevator triggers.

Read each individual mover for more info on this Mix mover.

 Gradual Mover
The gradual mover is a mover desinged for more than one trigger.
It will move one keyframe for each time a trigger is activated.
You might say that this is more like a "quest" type of mover there
a player has to activate more than one button/switch to get the mover
to "open" to it's fullest.

This is its specific properties:
CloseTimes[X] - Time mover use in the close movement.
Events[X] - The event tag to be activated when the movement is complete.
OpenTimes[X] - Time mover use in the open movement.
Tags[X] - This the tag connected to each keyframe.
You need to change the InitalState to GradualTriggerOpenTimed.
(There is other selections but I didn't get them to work correct).

On the trigger you need to change the event to the tag[X] for
each keyframe (one trigger for each keyframe).
The first trigger that activates the mover to move from keyframe 0 to 1
must have the same Event name as the movers Tag[0].
Tag[5] would then be the tag for movement from keyframe 5 to 6.
It also seems that the mover will not move to any keyframe unless
the preceding keyframe has been activated.
This means that you need to activate the triggers in the correct order for it
to fully open.
The red lines you normally see between trigger and object is also gone.
(Remember to set the correct amount of keyframes (NumKeys)).

 Loop Mover
This mover will keep move through all its keyframes repeatedly
until the trigger is no longer active.
If the mover, however, is blocked it will stop moving.
You also need to set the Initial State to LoopMove.
(Remember to set the correct amount of keyframes (NumKeys)).


BB Drac - Unreal Tournament UED2 guide Movers, simple door

Simple Doors

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Here we are going to create a simple "touch" open based door.

First start by creating two 256x256x256 rooms and
place them 128 units apart.
Then create a 128x128x128 brush and place it at floor
level between the two rooms and subtract it.

Add texture and light.
Screenshot

Now we are going to create the space in which our door
will move to when being opened.

Create a brush 128x128x16.
Place it at the middle, but at the side of the connecting section as
shown on the picture, and subtract it.
Screenshot

To create the door create a brush with the same size as the the last one
128x128x16.
Place it inside and in the middle of our small passage, right below the
small opening we created for our door.
Select another texture for the door if you like and press the "Add Mover"
button.
A purple framed brush should appear.
Screenshot

Now we need to make this door open and close.
Press the right mousebutton on the frame and select "Mover" and "Key 1".
Move the door up into the hole.
Screenshot

The change we did now affects the key frame 1.
Now press the right mouse button on the door again and select key 0.
The door should now move back into position and this is the position we want
it to start in.

If you add a playerstart now, rebuild and try the level you will have a
fully functional door.

There is no sound connected with the door yet but it will not be
explained in this tutorial.

If the texture on the door is wrong you can change the texture if you
have patch 4.36 installed.
Press the right mouse button on the door and select "Mover" and then "Show polys"
and then change the texture as you would a normal wall.

Also check my "complex brush" tutorial on how to create more complex and
nice looking doors.


BB Drac - Unreal Tournament UED2 guide Movers, advanced door

Advanced Doors

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

In this tutorial we are going to create a door activated by a button.
The door itself will be made with two movers and stays open/closed until some-
one press the button.

Start by creating two 256x256x256 rooms and place them 256 units apart.
Then create the passageway 128x128x256 and place it, at floor level
between the two rooms and subtract it.

Light and texture as you feel.
Screenshot

Now we need to create the two holes/slots our door will move into when activated.
Create a brush 128x64x16 and place it to one of the sides in our middle
passage and subtract it.
Create another one and place it on the other side and subtract it.
Screenshot

When that is done, keep the brush but move it into the passageway just outside
the slot.
Select a texture you want for the door and then press the "Add mover" button.
Do the same with the other side of the passage.

You should now have two movers blocking the passageway.
Screenshot

Now, we will need that fancy looking button you need to press to get those doors
open.
Create a brush 16x16x16 and place it somewhere at the wall close to the doors.
Change the grid setting to 8 and move the brush into the wall.
Then subtract it.
Move the brush out again, select the texture you want for the button
and press the "Add mover" button.
Screenshot

Now we start adjusting our movers.
Select one of the door parts, press the right mouse button, select "Movers"
and "Key 1".
Move the door mover up into the hole/slot.
Do the same with the other door part and also with the button.
Screenshot

Now return all movers back to the first position by selecting "Key 0(base)"
on all of them. This is the position they will start in when playing the level.

We also need to change some properties of the movers and we will add some
sounds so open the sound browser. Load the sound package "DoorsAnc".

Now to the properties.
The two door parts must have the same properties so change the following:

Events, Tag: a_door
Object, InitialState: TriggerToggle

So to add the sound effects you expand the "MoverSound" and open the
sound browser again. Select the "DoorsAnc" package and group "Stone".

For the MoverAmbientSound add the "sdoorL1" sound.
For ClosingSound and OpeningSound add the "sdoorS1" sound.
For the two last ones, ClosedSound and OpenendSound add "sdoorE1" sound.

Now the doors is actually complete.
The button however need some properties adjustment too.
Change the following:

Events, Tag: door_trig
Events, Event: a_door
Object, InitialState: BumpOpenTimed

(We will not bother with sound for the button).

Now you will see that two red lines is connected from the button to the
two door parts.
(If not the tag on the doors is not equal with the event on the button).

As things work now, whenever someone touches the button and when that button
has completed its move cycle it will activate the doors.
The doors will open and stay open until someone press the button again.

If you press the button, the door close and you quickly move to the other side
you can never walk back again.


BB Drac - Unreal Tournament UED2 guide Movers, simple elevator

Simple Elevators

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

This tutorial might be the least complex one of them all.
We are going to create a large room with an elevator to nowhere.

Subtract a room 512x512x512, light and texture it as you like.
(I hope this doesn't need a picture).

Create a new brush 16x128x128 in size.
Place this at floor level in the middle of the room.
Select a texture you want for this elevator and then
press the right mouse button on the "Add mover" button and
select "ElevatorMover".

A purple framed mover should appear.
Screenshot

Now press the right mouse button on the elevator and
select "Movers" and "Key 1".
Move the elevator up to around the middle of the room.
Screenshot

Press the right mouse button on the elevator again
and select "Movers" and "Key 0".
The elevator should move back to floor level and this is
the position we want it to start in.

Now open the properties for this mover/elevator.
Under "Object" and "InitalState" it is now "BumpOpenTimed".
We want to change this to "StandOpenTimed".
Close the properties window.

If you want to test it add a playerstart and rebuild.

As you can see the elevator works fine.
No sound though.

If the texture is wrong you can change it if you
have patch 4.36 installed.
Press the right mouse button on the elevator and select "Mover" and then "Show polys"
and then change the texture as you would a normal wall.

Also check my "complex brush" tutorial on how to create more complex and
nice looking elevators.


BB Drac - Unreal Tournament UED2 guide Advanced Mover, Looped Light Mover

Looped Light Mover

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Why not create lights a bit different than you normally would?

With a mover, a few lights and a trigger you can create alot of nice
effects.

To be able to follow and understand this tutorial it is important that
you understand lights, movers and triggers.

First of all I created a large room and placed a pillar in the middle.
The pillar should not be too thick.
(I did not add any default lights to the room).

The mover I created by first adding a hollow cylinder with
slightly larger "InnerRadius" than the pillar.
Then I added four cubes to each of the four sides of the hollow cylinder.
Gave all sides a default texture and the sides facing outwards a light texture.

At last I created a large brush and Intersected it to get the mover I wanted.

Screenshot

I placed the mover at the bottom of the pillar, close to the floor, added as a LoopMover.
To each side I also added a light, with the spotlight and direction facing outwards.

Screenshot

I gave all the lights the same "AttachTag" under "Movement", "LoopLights" as this is the
tag of the mover.
All lights also have "bMovable" true, "bStatic" and "bNoDelete" false so that the lights
can follow the mover around.

The mover must have some movement.
For the second keyframe (keyframe 1) I moved the mover almost up to the top
the pillar, close to the ceiling.
I also rotated the mover a few circles to give it the twist.
The reason for this is that under "Movement" you have the property "Rotation"
which remember what and how much rotation you have given the object.
This is why this mover will move from keyframe 0 to 1 and rotate around the pillar
aswell.
This is the mover properties:
Events, Tag: LoopLights (the "AttachTag" of the lights must have the same)
Mover, MoverEncroachType: IgnoreWhenEncroached
Mover, MoverTime: 2
Mover, StayOpenTime: 0
Object, InitialState: LoopMove

As this is a loop mover we need something to trigger it.
This can be done with a TimedTrigger.
"bRepeating" should be false and "DelaySeconds" 1 or 2.
The event must also be "LoopLights".

This is it...

How do this work:
The trigger will activate the loop mover after 1 or 2 seconds and then go dead.
The mover will simply move from keyframe 0 and 1, and then back again, never stopping.
As the lights have the same attachtag as the mover they will move along with the
mover, up and down.
Thanks to the rotation of the mover for keyframe 1 it will also rotate, with the lights,
around the pillar, giving you the spinning light effect.


BB Drac - Unreal Tournament UED2 guide Advanced Mover, Rotating Door

Rotating Doors

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Doors, sliding up, down, left, right or just a more complex variation.
Isn't it possible to make doors other ways?
Ofcourse it is.

To be able to follow and understand this tutorial it is important that
you understand movers.

In this 'advanced' tutorial I show how to make two types of doors.
The first one, is a door that swing open and the other keep rotating.
Screenshot

First lets start with the right one, the rotating door.

It was created by crossing two brushes and then intersecting it to create one
more complex brush and then add it as a mover in the opening.

This is a mover, but we don't want it to move to any keyframe.
It should keep rotating forever.

To do this you need to set inital state to "None"
Then set "Physics" under "Movement" to "PHYS_Rotating".
The last thing to do is to set the RotationRate, Yaw to 5000 and make sure
that "IgnoreWhenEncroach" is selected.
(you can set any rotation rate you want and I believe that -5000
is more accurate as it is supposed to rotate counter clockwise).

Now you have a rotating door that looks like an entrance to
any finer hotel.

The second door, which swings open is almost as easy to create as the
rotating one.
The one thing to keep in mind is that a mover is located in the world by
its center handle (like all brushes and objects).
When a mover move from one keyframe to another it will move
the center handle from one position to destination.

Logical enough, if a mover rotate it will rotate around the center
handle.
This means that if you compare it with a regular door that is stuck
to the wall with hinges you need to make sure that the center handle
is at this location of the brush.

To create the door brush I first create the door somewhere in open space.
Then I create a twice as large (not height) builder cube and place it so
the center handle appear where I want the 'new' center handle to be.
Screenshot

As you can see on the image, the 'new' center handle will be placed
on the top right corner of the door.
Then intersect the brush and you have a mover that can be made to work
as a realistic door.

Place the door in the opening and then change to keyframe 1.
Rotate the door to its 'open' position and then select keyframe 0
again.
By default it have "BumpOpenTimed" and the only thing I changed is
the encroach type which I set to "IgnoreWhenencroach".

It is impossible to make a door swing either way depending
on what direction the player come from.
Simply because a mover move from one keyframe to another in sequence
which makes skipping frames impossible.

The "IgnoreWhenencroach" will enable the door to open, even though
a player stand in the way of it.
The player will not be shoved backwards either.


BB Drac - Unreal Tournament UED2 guide Advanced Zones, Traps

Traps

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Traps are pretty easy to create and are usually only constructed using movers and triggers.

To be able to follow and understand this tutorial it is important that
you understand zones, movers and triggers.

This tutorial have three different traps which is a pressure zone, trap door and falling slab.
(All with deadly outcome).

I have created three different rooms with a trap in each.
The first room have the pressure zone trap and it works exactly like the trap in "DM-Pressure.unr".

Screenshot

From the picture you can see that there is a "steel" room with a mover working as a "falling" door.
The 'steel' room is zoned and have a "PressureZone" actore placed inside.

When someone fire at the trigger (inital state TT_Shot) it will trigger both the door and the button mover.
(Button mover do not affect the trap itself).
When the door close completedly it will trigger the pressure zone which perform a given effect
specified with the "PressureZone" properties.

PressureZone, DieDrawscale: 1.25
PressureZone, DieFatness: 255
PressureZone, DieFOV: 165
PressureZone, EndFlashFog: [X=1] (which is the same as the red color)
PressureZone, KillTime: 4

The trigger have a trigger time delay so the pressure zone and the door will be able to return to
their original state before triggered again.

The good thing about this is that the person who triggered the trigger will get a frag
as the game 'remember' who triggered the trigger and who died in the pressure zone.

The second trap is a lava grave.
It have two movers working as trap doors.

Screenshot

When someone shoot the trigger (inital state TT_Shot) it will trigger both trap doors
and the button mover (which have nothing to do with the trap).

The trap doors swing open, downwards, and anyone standing there will fall down into lava.

A thing to notice is that the trap doors might not "swing" correct because the center handle
should be placed at the vertex that "connect" with the wall.
(Like the hinges on a door).
Otherwise the mover will move inwards a bit and make it look like it swing backwards first and then
down.

This trap will not reward the "killer" with a frag, but the unfortunate player who falls down
will get a frag penalty.

The third trap is just a "falling" mover.
It will look like a slab of steel crushing anyone who stand under it when it falls.

Screenshot

This trap is triggered in the exact same manner as the two above.
With a trigger (init TT_shot) that trigger both the "slab of steel" and the button mover.

The "slab of steel" mover have "CrushWhenEncroached" to kill any player standing in its way.

I have not included any graphical means of pulling the "slab of steel" up and back to position again.
This could be chains or any mechanism to make it look more "realistic".

 Bot support for traps:
Bots do not trigger things just because they think it is fun or anything.
You need to tell them what, how and when to do things.
This includes traps.

In the actor browser, under "Inventory" you have "TrapSpringer".
By placing this close to the trigger and setting the following properties, you can get bots
to activate traps.

TrapSpringer, bShootIt: True or False if the bot need to shoot the trigger or not.
TrapSpringer, TrapTag: This should be the tag of the activation trigger (most cases the mover).
TrapSpringer, TriggerTag: The tag of the trigger which must be 'triggered' to make the trap work.

I have not placed "TrapSpringers" in this example as there is no bot support.

If it would have been, the "TrapSpringer" for all traps would have the "TriggerTag" for the trigger
and "TrapTag" to the mover(s).
Also "bShootIt" would be true for all.


Unreal Editor Maximum [unrealism.com/unrealedmax] - Movers (Doors and Elevators)

MOVERS - DOORS AND ELEVATORS

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This will be a small tutorial that will show you how to make (and make use of) doors and elevators - referred to as movers -in your level and general movers. I will be dealing with it all at one shot - sounds, different triggers, etc.

A SIMPLE DOOR

Making a simple door .......... is well simple. Here are the steps involved:

  1. First make the rooms and the passage where you want to put the door. Lets take my example. First build a room 512x512x512. Next build the passage where you will put the door in the dimensions 256x256x512. Next build another room leading to the passage in the dimensions 512x512x512.

  2. In the Slums.utx in the miscellaneous subsection select the door02 texture. Now build a brush that is 256x256x16 units. Place it in the middle of the connecting room. Now all you need to do is hit the Add Mover Button - [image]. Once that is done move the brush to the right and hit the add mover button again. This is how it should be in the various veiws:

    You will not be able to see the purple mover brush until you move the red builder brush out of the way. I have made the door out of two pieces.

  3. You need to make a place for the door pieces to move into. I you didn't you will see some weird stuff when playing the level. Using the same brush as before just cut a hole in the wall on either sides of the mover. Your top view should look like this:

    Now the pieces have a hole to move into ............... and like they say get mind out of the GUTTER! ;).

  4. Texture Alignment:- We now need to see that the mover brushes have got their faces aligned properly. To do so you need to first select both movers, right click on them and in the menu go to movers (not mover properties and hit show polys). What happens now is that you will see the mover in the 3d view in all its textured glory:

    As it so happens the face of the mover is not aligned correctly. So just select it go to the texture properties and under the alignment tab hit one of the U-Pan buttons until the texture is aligned correctly. That's all your mover is now perfect (well almost).
    IMPORTANT NOTE: The show polys thing is just temporary and once you rebuild the level the polys are removed from the BSP. But it retains the texture alignment that you would have carried out on it.

  5. KEYFRAME (IMPORTANT): This step is very important. If for some reason your door does not work check that you have done this step. The keyframes thing tells the door to what position it should open to when touched. since we want one part of the mover to move to the left and the other to the right that is exactly what we will do. Select the left mover (in the 3d view) right click and in the menu that pops up hit the Key 1 value (refer picture above). Now drag the mover in the top down view completely into the "hole" that we made for it in step 3. Now right click the mover and hit movers/Key 0(Base) and the mover will move back to its initial position. What happens is when you touch the door it will open, i.e. move to keyframe one and after some time it will close by moving back to key frame 2. Verify that the left mover works by hitting movers/key 1 - it should move to the left and when you hot Key 0 it should move to the right and "close". Do the same for the right door.

  6. That all!. Add in some lights and a player start. Rebuild the level and play it. When you touch the doors it should move to the right and left and after some time it should close.

TRIGGERING A DOOR TO OPEN

You would have noticed above that the doors move very funnily when you bump into them. Bumping doors open can be good for some doors but in this case they are not. You can have the doors open when a player touches a trigger. A trigger works exactly like one of those automatic sensor doors. When the person is within the radius of the sensor (trigger in UED) the door stays open once the person moves out of the range of the trigger the door closes.

First locate and place a trigger from the actor class browser - its located under Triggers/ Trigger (don't expand it just choose a plain trigger). place this actor in between the 2 doors in the 3d view. Now all you need to do is tell the editor the when the player touches this trigger (sensor) the door should open. First go to the triggers properties and expand events and in the event line enter a unique name:

Now go to the two doors (movers) properties and under events in the tag line enter the same unique name that you used above. Now in the top down view they should be connected thus:

Now go to both the movers properties and under Object/Initial state from the menu select trigger open timed. This tells the mover that it has to be opened when the player touches the trigger and not when he bumps into the door like in the previous step.

The final thing you will need to do is to set the collision radius and height of the trigger (think of it as the range of the sensor). First ensure that actors are in radii view in all the views (to do so right on the top of the 2d or 3d views and in the menu that opens scroll down to actors and check radii view, to turn it off check full actor view). The radii view helps to determine the radius of the actor when it is selected by drawing a red circle in the 2d views and by way of a cylinder in the 3d view. Now go to the triggers properties and under collision change collision height and radius - I set it to 64 and 128 respectively. See below:

NOTE 1:- Various Object/Initial States:

You would have noticed that the mover has many more object initial states here are what they all do (naturally you need to first set up the triggers as described above before making use of these initial states):

  1. Bump Open Timed: When the player touches the mover it opens, remains open for a certain period of time and then closes.

  2. Bump Button: Nobody uses this and probably never will . IGNORE.

  3. Stand Open Timed: All lifts and elevators must be set to stand open timed as the bots wont know how to use the lift otherwise.

  4. TriggerPound: When set to this, on the actor touching the trigger the mover will keep moving between key frame 1 and key frame 0. Great for machinery.

  5. TriggerControl: Actually the trigger control works more like the automatic door sensors stated above. When the player is within the radius of the trigger the door will stay open. Once he moves out it will close.

  6. TriggerToggle: You need to touch the trigger each time that you want to open or close the door.

  7. Trigger Open Timed: When trigger is set off by player opens and after a certain amount of time closes. This is the most common type of initial state that is used.

NOTE 2:- You can have a door open when the player touches a button. To do so make the button and door. Set a unique name under the buttons events/event and give the same to the doors events/tag. Also set the object/initial state of the button to bump open timed and the object/initial state of the door to trigger open timed (note that buster!).

MOVER SOUNDS

The mover sounds very odd without any sounds lets correct that and give the mover some sounds. First go to the movers properties and expand Mover Sounds. Now open the sound browser and load the sound package DoorsMod.uax - as the name suggests it contains all the modern door sounds. Now you need to select a group of sounds that you want to use and is appropriate for the level. The convention for using the door sounds is usually using done like this:

Notice that I have used the mlift7series as they all "match". Here's what they all do:

OpeningSound - When it starts opening.
OpenedSound - When it has finished opening
ClosingSound - When it starts closing.
ClosedSound - When it has finished closing.
MoveAmbientSound - Optional ambient sound when moving.

In most cases the sound with a name end is used for the closed and opened sound, the sound with the name start is used for the closing and opening sound and a looping sound is ALWAYS used as the move ambient sound.

ELEVATORS AND LIFTS

An elevator is a mover brush that goes up whereas the door mover moves from left to right. So its the same when it comes is keyframes. The only difference being that since there are no lift textures you'll have to build the lift separately. To do this first make the area that the mover is going to move in, in your level. What you need to do is subtract a brush off to the side of the level and build your lift in here. After building the lift just intersect it with a larger brush and place it in the area that you made for the lift to move in and hit the add mover button. Remember that if you made part of the mover with an masked decoration like a grate you may need to make an invisible collision hull and intersect it along with the rest. Don't forget to set object/initial state to stand open timed as the bots will not understand anything else. Set the mover keyframes (instead of it moving left the lift just moves from bottom to top and vice versa) and sounds as shown above.

ADDING BOT SUPPORT FOR MOVERS:-

Whereas you need not add bot support for doors, elevators require a special setup if you want them to be used by bots. This seems to be a common question that begginners keep on asking in the forums but its actually very simple. Here are the "5 steps":

  1. The first thing to do is give the elevator a unique name under the movers events/tag (note that u need to set the tag not the events).

  2. The next thing to do is locate something called the lift center. its located under navigation point:

    Now without expanding lift center in the actor browser just select it and place the lift center exactly in the middle of the lift and a little above it. Now go to the lift center's properties and expand lift center. Under that you will find a entry for LiftTag give it the same name as the unique name that you gave the lift in step1.

  3. Oh my god! we're at step 3 what an achievement ....... well never mind the sarcasm ;0. Its time to place two lift exits. This actor tells the bots where to get of the lift at the bottom and where they can get off at the top. Now place the two lift exits in the necessary place. Go to their properties and under LiftExit you will find an entry for LiftTag - set it to the same tag as the mover. In short words you need to set the tag of the lift, and just enter the same under the LiftTag field in both the LiftCenter and the LiftExit.

  4. Now do a rebuild of paths. In the 3d view right click on the tool bar and from the view menu choose show paths and you should see the two lift exits and the lift center connected with a blue line:

MOVER PROPERTIES/MOVER

If you go to the properties of any mover brush and expand mover you get a set of very interesting options. I will explain a few important ones. If you want to know what the rest of them does, just right click on the mover and hit edit script in the box that opens read the commenst that are written by the Epic Games programmers in green and you should be able to get it. The ones used most often are marked with a * .

  • bDamageTriggered - The mover opens when it takes damage, i.e. when it is shot at.

  • bDynamicLightMover - The mover has the ability to reflect dynamic or changing lights.

  • bTriggerOnceOnly - This mover can be triggered only once after that even on touching the trigger the mover will not be activated. great for one time only puzzles or traps.

  • BumpType - Not used in UT but if you are making maps for the original Unreal1. You can set it to be opened only by the player, or only pawns will be able to open the door or any one can open the door

  • MoverEncroachType - ME_ReturnWhenEncroach: after hitting player returns to previous state; ME_StopWhenEncroach: On hitting player remains at current spot; ME_CrushWhenEncroach: When the mover hits the poor sod of a player it crushes hit to death (see below); ME_IgnoreWhenEncroached; ignores actors/players.

  • EncroachDamage - If you set the above to ME_CrushWhenEncroach set the amount of damage to be inflicted on the player here.

  • MoverGlideType (*)- MoveByTime: If set to this the mover moves at a constant rate from key 0 to 1 and back, GlideByTime: If set to this mover accelerates from key 0 to 1 and back again.

  • NumKeys - This determines the number of keyframes in total. Say for example you had an collapsing plank that goes through 2 different "falling places" - if you wanted the plank to first fall on a ledge below it and then into some water below the ledge this is how to do it. Just set the NumKeys to 3 and hit movers/key 1 and move it to the first place that you want it to fall into - say a ledge below. Now hit key 2, the mover will move back to key 0 - this is normal - from here put the mover into the water. Now on being triggered the plank (mover) should first fall on the ledge and then into the water.

  • MoveTime (*IMP) - This is the amount of time that it takes for your mover to move from key 0 to key 1 (and then back again). 1 is a perfectly good number, and .75 moves it a bit more slowly. It depends on your level. If you have a door sitting in the thick of the action you wouldnt want it to take forever to open so you would naturally give it a shorter move time.

  • StayOpenTime (*IMP) - This determines how long the mover sits at Key 1, before beginning the journey back to Key 0. 4 gives the player a lot of time to move his ass off the lift or out of range of the door.

What happens is that the door moves from key 0 to 1 taking the amount of time given in move time and then sits at key 1 for the amount of time given in StayOpenTime, it then closes i.e. moves back to key 0 from key 1 by the amount of time given in move time. The way in which it opens is also governed by MoverGlideType i.e. acceleration or smooth time move.


Unreal Editor Maximum [unrealism.com/unrealedmax] - MOVING DECORATIONS

MOVING DECORATIONS AND ATTACH MOVERS

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This tutorial will deal with how to make certain preconfigured decorations like the escape pod and cars move. It will also provide in-depth instructions on how to make use of the attach mover. Since this is my first tutorial its probably not up to the mark so bear with me.

NOTE: To make your own custom boats, fighters and have them move in a realistic way read my miscellaneous keypoints tutorial on this site.

STEPS INVOLVED

1. First create a cube 5000x1024x1024 -can be how much ever you want but make the height quite large, choose a texture and subtract the brush. This we will call the "pod room".
2. Change the cube properties to 256x256x512 (or whatever :)) and place it next to the pod room so that both are connected and subtract it so that both these rooms become connected.
3. Create a very basic Skybox 1024x1024x1024 place lights and a SkyZoneInfo from under Info|ZoneInfo . Also set the surface properties of the top of the pod room to fake backdrop.
4. From the drop down menu on the right choose classes. Expand decoration then choose escape pod and add one into the pod room. Make sure it rests on the floor and is in the middle of this room.
5. IMP: Expand Triggers and add in a plain Trigger (probably in the first room). Change its event under Advanced Properties|Events to podpath(or whatever). Still under its properties expand trigger and set bTriggeroneOnly to true so that the event doesn't keep happening. Of note here is the fact that nearly, any other actor that you add into the world be it a mover or an earthquake or explosions the tag will most likely be podpath. This means that once you hit the trigger all these events take place simultaneously the pod launches (coming to that in a moment), walls explode, there are explosions, sounds, etc. all happening at the same time.
6. At this point you're probably wondering how the hell do you launch this damn pod into space anyway (otherwise u wouldn't be reading this tutorial, right?) . Well this ones secret is something called the Attach Mover. I could probably explain it here, but there would be no point as the Epic guys have given a much better explanation than I ever could. After selecting classes from the pull down menu on the right expand brush then mover - yippee! finally getting to use that one (which I never did before using the pod). You should see various types of movers, double-click Attach Mover and when the Unreal Script box opens see the note written in green. You may also be wondering why I didn't just copy and paste it here but check out what it says on the bottom of this page. That should explain what the darn attach movers do.
7. Ok next build a cube really small like 5x5x5 rotate and intersect it so that only a small triangle is left and place it just below the pod. Make sure its totally in the pod room. With attach mover still selected under classes hit the mover button(6th on 3rd column). Got to its advanced properties and its title should be attach mover. Set its advanced properties to the following:
Events|Tag to podpath so that the trigger and mover are connected; you should also set Mover|bTriggerOnceOnly to true and use sounds under mover sounds. Under mover you also need to set movetime to around 20 or higher; NumKeys to around 6 (note NumKeys not KeyNums that another option altogether); I also set the stay open time to an impossibly high number like 99999999 or something. Under attach mover set AttachTag to EscapePod which is the default tag of the pod. Expand Object and change InitialState to Trigger Opened Timed.
Now under the pods properties it must be Events|Tag - EscapePod and under Mover|AttachTag set the value again to EscapePod, you have to do this or it probably wont work.
8. Ok we'll go back to the pod in a minute before that I just set a lot of effects. Some are located under Effects - explosion chain (I set around 10 and placed them around the room); earthquake (under keypoint) ; smoke generator (under keypoint); TriggeredDynamicAmbientSound (under keypoint) and set every one of their "tag" under events to pod. I left their default settings in place (for the earthquake I used the quake sounds from AmbOutside under Sond|Ambient Sounds. Phew! that one little trigger dude controls virtually everything.
9. Make a skybox 1024x1024x1024 (just use a night texture) off to the side and then place a skyzoneinfo from Info|Zoneinfo.
10. Back to the pod now. I built a cylinder right at the top of the pod room and subtracted. We are going to show the pod moving up and then entering the cylinder. If you learn how to do that you should be able to make the pod do any convoluted movements that you want it to do and I need'nt explain. The pod moves along with the attach mover so when we set the key frames of the attach mover the pod will move along with it. Of course you can see this only in the game. Right click and go to mover key frame and set key 1 to the end of the height of the pod room. Now by right-clicking the attach mover go to mover keyframe and hit Key 2, when you hit this it should move back to the starting point and that's normal. We need to set the "second phase" of movement from there so to speak. I did this by rotating the attach mover in one of the side views. I then again hit mover|mover keyframes and key 3 and set the attach mover at the outside of the tunnel and the level. I also set the surface properties of the end of the tunnel to fake backdrop. After this you should now be able to make the pod go through any kind of motions and any amount of twists and turns.

INTREPOLATION POINTS

NOTE: Read the interpol tutorial for more information.

That's it rebuild and enjoy.

UNREAL TOURNAMENT NOTE:

There is no need to confine yourself to the Escape Pod. Under decorations you will find cars and fighters which use the same technique. Cars are used in the opening sequence of UT and the fighters are used in DM-HyperBlast. To use them do as you would with the escape pod and the attach mover. A cool thing that you can do with this is to place fighters in your SkyBox and use the attach mover to send them across in end assault sequences, etc.


Unreal Editor Maximum [unrealism.com/unrealedmax] -DIFFERENT MOVER TYPES

DIFFERENT MOVER TYPES

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

Up till now I think a lot of you would have used only the standard mover that is created by hitting the mover button. Here we'll discuss a different way of creating different types of movers.

HOW TO CREATE THE MOVERS DISCUSSED HERE

For all the mover types discussed here just expand Brush|Mover under the classes menu. Select the type of mover that you want to add. Go through the door/mover creation process by adding, intersecting the brush, etc. Now on placing the builder brush where you want the mover to go, just hit the add mover button. VIOLA! the type of mover that you selected in the classes menu will be added in instead of the normal mover. We'll just discuss the function, use and setup of these movers. To see a full blown explanation for each type of mover just open its script box and read the explanation given by Epic in green. Alternatively after creating the mover brush just right click on the mover and select the type of mover that you want to add in, thus:

WHO THIS TUTORIAL IS FOR

To understand this tutorial I expect you to have read all the other mover tutorials on this site and be very familiar with movers. You should know how to make proper movers and just be looking for something different that may suit your level needs better than a normal mover.

I. ROTATING MOVER

Why bother trying to set a normal mover to rotate when you have all the settings pre-configured for you?. This is the easiest way to create a rotating object or mover. Make a circular brush off to the side, intersect it with a larger brush and place it in a box in your level. Place some lights and a player start here. Choose classes from the browser, expand brush then mover and select rotating mover. Hit the add mover button. You just added in the rotating mover!. Go to the rotating movers properties and set object initial state to none - this actually depends on the situation, if you want the rotating mover to keep rotating forever set it to none, if you want it to be set of by the trigger naturally set it to trigger opened timed (remember to set the tag then). The only other thing you need to set is the rotate rate under rotating mover. For this example just set yaw to 1000. That's it no need to set anything else!. Play your level and see it spinning around. For different types of rotation just play around with the yaw, roll and pitch values. COOOL!.

II. ASSERT MOVER

Read the explanation given in the script box - there's no way I could top that explanation. In the properties of the assert mover the usual mover properties are present along with assert mover. Set the usual tags, initial states etc. You [image] need to set the properties of the assert mover like to the following:
a. bOnceOnlyStopOpen - True in this case. If it is false it will go to the first key frame and stay there forever. The stay open time under mover will affect this value.
b. CloseTimes - This defines the move times for each key frame.
c. OpenTImes - How much time the door takes to open by going through each key frame. Say your door moves using 3 keys, you can specify how fast the door should move at each key.
d. WaitUnAssertTime - Very important. When the player steps out of the radius of the trigger the mover will stay at its current key frame say 1 and wait until this value has been reached. Then the mover will move all the way back to the beginning - key0.

III. ATTACH MOVER

This is a mover I find myself using quite a lot. You can make any actor attach itself to this mover. The actor and the mover will move together - defined by the key frames. The tag of the actor/decoration must be the same as the one entered as the attach tag under attach mover in the attach movers decoration. You know its getting really boring writing about this attach mover again and again.

IV. ELEVATOR MOVER

Don't even bother the standard mover will do.

VI. GRADUAL MOVER

I would say that this is the best type of mover to use for a door or drawbridge or whatever that shows moving parts. What the gradual mover does is that when the first sequence of movements is over it waits for StayOpenTime to get over and then commences the second set of movements. Lets take the draw bridge example. Say you set the trigger and want the draw bridge to open on hitting this, all the while showing moving chains etc on the side that seem to be lowering the drawbridge, it fully opens waits for some time and then closes behind you. Set the mover normally and all its key frames etc. as you would normally do. Set a trigger in front of it to open the drawbridge. Under the gradual movers properties expand gradual mover. This is the place to set the tags not under events. Close times and open times are how long you want the draw bridge to take to move at each key - I set close times to around 90 and open times to 5. Enter the tag that you gave the triggers event under tags 0. If bTriggerOnceOnly is set to true then the gradual mover only completes the first set of sequences. Lets imagine that you want moving parts for the mover, like a rotating thing that seems to pull up the draw bridge just set yaw under rotation that's all - the rest is the same as the above gradual mover properties. You should also take note of the fact that a gradual mover adds new states to the oblect|initial state. Namely - gradual trigger opened timed, gradual trigger toggle and gradual trigger pound. Just use these instead of the normal trigger opened timed that you'll find there. That is where for a normal mover you would set trigger opened timed, for the gradual mover set gradual trigger opened timed. This is not to say that you cant use the normal trigger opened timed, you could also use the normal bump open timed. May your moving parts be superb!.

VII. LOOP MOVER

For example (shit goddamn it I cant find a better way to explain it so I'll have to use the same crap again and again, ok!) if you were to set a loop mover as a door, where a normal door would lets say slide to the left and then slide back to the right a loop mover will slide to the left and just seem to appear at the starting point again instead of sliding back and forth. Make sure u set loop mover properties > object > initial state to loop move :).

VIII. MIX MOVER

This mover is a mix of the features of the attach mover and the gradual mover. Since I've already explained above how to use these two you should be able to configure this. You should use this in places where you want the attach mover to be a gradual mover or vice-versa.

That's all the mover types there is. If you still have any doubts please email me.


deCyber Build Section

Movers

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Downloadable files : Movers.UNR
(Demonstrates a perpetual mover using 2 movers - a dispatcher could also be used)

1) Preparation
2) Placement
3) Movement
4) Properties
5) Other_Movers
6) Tips

Introduction

Movers are an essential part of any map you create. These can range from simple doors and lifts, to complex items such as exploding walls and machines. There is a great deal of possibilities when using movers, and I know I’ve only scratched the surface of what is possible. In this tutorial my aim is to go over some of the basics needed to create these.

Preparation

1) The first thing you need to do is build the item you want to become a mover as a normal static object in a separate area from the world you are creating. Build a box, say 1024 x 1024 x 1024. This will be where you create the brush that you eventually want to be a mover. (We'll call this the "build room")

2) Build an object in the usual way by using cubes, cylinders or whatever you want, with all the textures set just as you want them.

3) Now, reset your cube brush so that it surrounds the whole of your object with room to spare.
(Make sure that your cube isn't touching the sides of your build room). e.g. Your object might be another box which is 64 x 64 x 32. Make your surrounding brush 80 x 80 x 50, that will be fine.

4) Now click on the "intersect" icon. If you've hit the right button your red brush should have snugly wrapped itself around your object to mimic it.

Placement

5) The next step is to drag this brush to wherever you want to put the mover. Once you're in position, click on the mover icon that looks like a sheet with arrows coming from it. If you've hit the right icon, your new mover should appear in your view screens as a purple outline.

Movement.

6) To make your mover actually move, you need to tell it where it’s moving to. Click on your mover brush and you should see it highlighted as an even brighter purple.(Make sure you click one of its lines and not on one of its vertices, I'll explain later).

7) Now, while your pointer is positioned on that brush, right click with your mouse. You should see a drop down menu. One of the menu items should read "key frame". Click on that.

8) When you first added your mover to your map, it will be automatically positioned at "keyframe 0" That is its resting position. Click on key frame 1. This will be your movers first destination (frames 2 onward are further sequential movements). Now move your highlighted mover brush to the position you would like it to move to.

Note:
If you are rotating your brush. It will rotate on its "swivel point". The swivel point can be seen as a vertex that is a small star. To change the swivel point, just click on a different vertex and it will rotate on that. Now reset your brush to key frame 0

Mover properties.

9) With your mover highlighted, press F4 (or click on mover properties by right clicking). A box will appear with all the properties of your mover. Here are the things you need to add information to
(I don't bother with the other properties).

EVENTS:
Event:
When the mover has finished its moves, you might want it to trigger something else.
Just write the tag of the other event in this field.

Tag:
If this mover is triggered by something else, other than it being hit,
you'll need to give it a name.

MOVER:
BeDamageTriggered.
Set this to true or false depending upon whether you want it to move when
its shot at. (You will also need to set Object to "Trigger toggle")

BeDynamicLightMover.
This is also true or false. This means that it will respond to light as it moves
(set as true) rather that stay at one fixed light setting. It will receive the light
at wherever you have set the swivel point.

BeTriggerOnceOnly.
Again, true or false. If you only want it to move just once, then set this to true.

Bump event.
If you want something to be triggered when you bump into this mover then put its tag here.

Bump type.
This mover can respond to either the player, another pawn such as a monster, or anything

DamageThreshold.
If you want the mover to take a battering before it actually shifts, give it high health in this field.

EncroachDamage.
If you get in its way when its moving and you've set it to "stop" or "return on encroach" It will hurt the pawn by the amount you put in this field.

KeyNum.
Your mover might have more keyframes than just 2. If so, you might want to start it from any of those. Put that number in this field. Usually you would keep this as 0.

MoverEncroachType.
Can be set to: Stop, Return, Crush or Ignore. This should be self explaining. Your mover will react in one of these four ways if a pawn gets in between the mover and its destination.

MoverGlideType.
Can be set to "Glide by time" or "Move by time". "Glide" creates a gradual transition between the frames (slows down and speeds up between each frame). "Move" starts and stops instantly.

Move time.
This is the length of time you want it to move between each frame.

NumKeys.
If you're mover, has more than one frame, you'll need to tell it how many in here. Remeber that "0" its resting position counts as 1 number. (That's why its usually set at 2 by default - open and closed)

OtherTime.
Haven't got a clue what that does! %-o

PlayerBumpEvent.
Place the tag name of one of your events in here, if you want your mover to trigger something the moment it starts moving.

ReturnGroup.
Dunno !

StayOpenTime.
Once your mover has finished its move (and if its set as a timed mover), it will stay open for the length of time you put in here, and then it will return through its frames.

WorldRayTraceKey.
You got me there! Your guess is as good as mine.

MoverSounds.
Use the soundfx browser to find an appropriate sound for your moving object to make when it is activated.
"Opened","Opening","Closed" and "Closing" all need to be one shot sounds and the move ambient sound needs to be a looping sound effect.

And finally...
the only other property you really need to be concerned about is this one:

OBJECT:
Its sub-property "Initial State", has to be set to one of the following:

Stand Open Timed.
This is used for lifts and anything that wants to move when a player stands on it. It will stay open for as long as the "StayOpenTime" is set for.

Bump Button.
I don't think anyone knows what this does !! :)

Bump Open Timed.
When the player walks into this mover, it goes through its frames, and stays open like the "Stand Open Timed"

TriggerPound.
Something will trigger this mover off. (You need to have another mover or a trigger with its event set to this movers tag) This mover will continue to move through its frames only as long as someone is still using the trigger. As soon as you leave the trigger, your mover will go back.

TriggerControl.
Is initiated only by a normal trigger actor.

TriggerToggle.
I use this a lot. Another trigger or mover (or a shot) will set your mover off. It will stay open until something triggers it a again, and then it will return.

Trigger Open Timed.
A trigger or mover will set this one off, and it will stay open for however long you want it to and then it will return.

That's basically what there is to making a mover.
Once you've added it to your world, and set its properties however you like, press F8 to rebuild and then you should be there.

Other Movers

Be sure to check out the "Brushes" section in amongst the actor class browser. Under movers you'll notice different kinds of movers such as, "Attach mover", "Gradual mover", "Loop mover", "mix mover" etc. I have a limited understanding of these, but in short here’s what I do know:

Attach mover.
This is used to move actors so that they mimic the mover brush. The mover and actor should both have the same "Tag". Checkout the Unreal level called "Gateway" if you have the Unreal CD. There’s a cool ship that moves around outside the window which is moved using this approach. The same is done in Nali Castle with a bombing space craft.

Elevator mover.
An "Elevator Trigger" should trigger this (see tutorial on TRIGGERS). This mover will move directly to the specified keyframe designated by the trigger. Very useful for puzzles.

Loop mover.
This will give you a mover that cycles its keyframes. When it reaches its last key frame, it will move directly to keyframe 0 without retracing its steps. This is NOT a perpetual mover, but with some careful planning it can be.
Study the UNR file in the ZIP to find out one way to do this. (hint: both movers trigger each other in an eternal cycle).

Gradual mover.
This will pause for different lengths of time between each keyframe, it looks like it can also trigger different events after each keyframe too.

Mix mover.
This has a combination of different functions from the other mover brushes, so that different abilities can be combined.

TIPS

Rotating movers
You may have seen maps with brushes in them that are continuously rotating (The impossible triangle in my map DM-deCyberEscher for example). Do do this, create a mover in the usual way but don't us the key frames. Instead adjust the settings in the "movement" properties of your mover. As a good bench mark for rotation, add a weapon to your map and check out the movement properties for that and copy that to your mover.

Disappearing movers?
If your map contains a lot of movers, you'll eventually find that whilst they are still solid, you can't actually see them in the map, or perhaps they flicker a great deal. A common way out of this problem is to right click on any mover in your map and choose "select all movers". Once they're all selected right click on one again (so that you can adjust all the movers at the same time) and choose "order ... to last" Then rebuild and you may well find that your problem is solved.

EZkeel
(Simon West-Bulford)


Mover Info

by Sniper3000

Sniper3000

http://www.planetunreal.com/utnewbie

This is my first tut so bear with me! Right, at the title says this is a tut movers.

Movers are most section of the level that moves, e.g doors, lifts, flying platforms, etc.

Movers are created by using ‘Keyframes’. These are the points that the lift/doors go through. This means to create a normal door or lift, you only need to use two. One at the start of the lift/door, and one where you want the lift/door to goto. Movers ALWAY travel directly between keyframes in a straight line. If you want to do a platform that goes round a square you need to use four points, one at each corner. Also the mover will always start at keyframe 0, known as the ‘base’ frame, and mover up the frames in numerical value i.e. 0,1,2,3,4,5,6,7, and then come back through the keyframes i.e. 7,6,5,4,3,2,1. To make a mover, create a brush, (red framed) and place a texture on it. Then press the ‘Add mover’ Button. (It’s the platform with the arrows on the button.) You should now get a purple framed brush. This is your mover. Now place it in the place you want it to start from, e.g. At the bottom of a tower.

Now right click on a line of your mover and select ‘Mover’ and then ‘Key 1’. Now move the mover to where you want it to goto. Goto ‘Mover’ and ‘Key 0’ and create your level. Now stand on/in front of the lift/door and it might move. If not try one of these: (Right click then ‘properties’)

MOVER

  • bDamageTriggered- Damage is needed to get the mover to move

  • BrushRaytracekey- Not quite sure ‘bout this one! I’d leave it alone!

  • bTriggerOnlyOnce- If yes, you can only trigger it once.

  • BumpEvent- Event to happen if mover is touched when state isBumpOpenTimed.

  • BumpType- What can move the mover (I think it’s like monsters or people)

  • DamageThreshold- How much damage if ‘bDamageTriggered’ is activated

  • DelayTime- Time before the mover moves when triggered. (e.g. Phoboes)

  • EncroachDamage- How much damage a play takes if hit by it

  • KeyNum- Current keyframe at start of level

  • MoverEncroachType-What happens when the mover hits someone

  • MoverGlideType- If it accelerates or move at a constat speed. (I prefer the first one.)

  • MoveTime- Time mover takes between keyframes

  • NumKeys- The amount of keyframes the mover goes through

  • OtherTime- ? Never had problems, so I leave it alone!

  • PlayerBump- Event to happen if bumped by player when state is BumpOpenTimed.

  • StayOpenTimed- How long the mover stays at the end keyframe

  • WorldRaytraceKey- Not quite sure ‘bout this one! I’d leave it alone!

MOVER SOUNDS

  • ClosedSound- Sound heard when mover has finished closing.

  • ClosingSound- Sound heard when mover starts to close.

  • MoveAmbientSound-Sound heard while moving, either opening or closing.

  • OpenedSound- Sound heard when mover has finished opening.

  • OpeningSound- Sound heard when mover starts to open.

If that doesn’t help then goto ‘object’ and to 'Initial State’:

  • None -You cannot trigger this. (Bit pointless actually! Unless you loop the mover)

  • StandOpenTimed- Goes through the keyframes, and back again.

  • BumpButton- Have NO idea! ( maybe like BumpOpenTimed but with a button??)

  • BumpOpenTimed- Goes through the keyframes, and back again.

  • TriggerPound- Keeps going as long as it is triggered.

  • TriggerControl- Keeps going if you are in the trigger radius.

  • TriggerToggle- Toggles mover between keyframes by trigger.

  • TriggerOpenTimed- When triggered it goes through the keyframes, and back again.

If that hasn’t helped then damn you! It took a long time to do that! :-) If you want to use bots in your level (If not think of other people!) Then you MUST use ‘StandOpenTimed’ and ‘BumpOpenTimed’ correctly. Bots see StandOpenTimed as lifts andBumpOpenTimed as doors. It is important you get that right!

If you wanna change the texture, and have 4.36 of UT then right click, and goto ‘Movers’ and then ‘Show polys’ and then you can edit the textures like normal.


Creating Doors

by Daniel 'dandeman2k' Marcus

dandeman2k@hotmail.com

OVERVIEW

The aim of this tutorial is to make you comfortable with creating doors (using movers). This will cover areas such as triggers and sounds as well.
Please Note: some of the pictures have not come at well when reduced but you can enlarge these pictures by clicking on them!!

ASSUMPTIONS

I assume that you know your way around unrealed 2.0 enough to be able to create a room without me going into detail.

CONTENT

Creating the doors

OK. We're ready to go. I will explain to you the concept of making doors using movers by giving you an active example. So don't worry if you get stuck, because you will be able to download the map we will create as an example by clicking here.

Firstly, open the texture browser (done by clicking the button which looks like a landscape at the top of the window) and load up ancient.utx . This is a nice texture package plus it come with a few nice doors!!! Now we want to create the rooms we want to join together using a door. Create a cube 512x512x512, choose a texture and subtract it . Now create another cube 256x256x512, and place it leading off the room we just created (make sure it is on ground level and subtract it. Now create another cube coming off that with the dimensions 512x512x512 and subtract it. You should now have three two rooms connected by a smaller room. It should look something like this:

Now, we shall put in the doors. To do this, we create a brush (cube) with the dimensions 256x128x16. Place this in the middle of the connector room on the right hand side, choose a door texture (for this tutorial I will use AGATEZ which is from ancient.utx which we were using anyway) and click add mover (the [image] button).

Move it to the left so it covers the rest of that connector room and click add mover again. Now move it to the left again so that it is coming out of the wall and click subtract. Do the same on the opposite side. Your top view should now look like this:

I will now explain why we have made apparently unexplainable wholes in the walls. They are there because when the doors open they are going to split (I will probably create another tutorial for advanced doors where they can move differently!!) the need somewhere to go because they are solid. Now that we've created the space, we can tell them how they are going to open (something we have not done yet!!).

Now select one of the movers in the top view (it doesn't matter which since we are going to do this to both) and right click on one of its lines and go to movers -> key 1 as in the picture below. Now slide the mover into the gap we made for it by holding down Ctr+left clicking on the mover while dragging. Once it fits the gap perfectly, right click along the line again and go to movers -> key 0 (base). The mover should now move back into its old position.

Now repeat with the other mover. You have now created basic doors, we will still need to refine them, but if you place in some player starts and lights and rebuild, you will be able to play with them. Don't worry about not being able to see the doors, if you write click go to movers -> show polys, you will be able to see them perfectly.

Adding a trigger:

If you did play it you would have noticed that although the doors opened when you run into them, you actually had to run into them and only one opened at a time. This is because they are not connected in any way. We can solve both of these problems by inserting a simple trigger.

To insert a trigger, you have to open the actor class menu by clicking the [image] button. To insert a trigger you then have to go to triggers -> trigger (only click once on trigger). This should look like this:

Once you have done this, you can exit the actor class menu. Now on the map in-between the doors right click (not selecting the doors, you might have to go slightly to one side but you can then reposition it) and go to add trigger here.

Now we come to the important part, which links the doors together and sets an area that you go into to make the doors open. Right click on the trigger and click on trigger properties. You should see a menu like the one below appear. Open events, and change event to doors1 like the picture below.

Now right click on one of the movers and go to mover properties (you will have to click on one of the purple lines). A menu like the one below will come up. Go to events and change the tag to doors1 like in the picture below:

In the top view you should see red lines connecting the trigger and the doors like this:

Please note: I have had to move the trigger off centre so you can see both lines. The trigger should be in between the doors like I told you (you will see why soon).

There are now only two more steps to placing the triggers. We have to go into the trigger properties again (right-click then got trigger properties). This time we go to collision and change collision radius to 200 as in the example below:

For the final step we have to go into the mover properties again (right click -> mover properties). This time we have to go object and change the initial state to trigger open timed as below:

You can now rebuild and save your map and play test it. You will see that the doors look a lot more professional. But there is 1 more thing I will show you in this first tutorial (I have now made up my mind that there is too much to cover in 1 tutorial so I am going to write an advanced one to accompany this!!) and that is...

Applying sounds to the Doors:

This is the last thing you need to make your doors professional, whereas in the next tutorial I will show you how to customise them and make them more complex (looking forward to it already, huh?? ;) )

To implement sound is simple, just go into the mover properties again and go to mover sounds. Firstly, lets choose a closed sound since that is the top of the list. Click on where it says none and you will notice three buttons come up beside it (clear, use and '...'). We want to browse for a sound first so click on the '...' button. A window saying sounds should come up. In this window, load 'doorsanc.uax'. You can now browse for a sound. I chose 'adend52', so click on it once then go back to the mover menu and click use. You set the rest of the sounds in the same way, and its pretty simple to work out when the sounds are implemented. You can see my choices below:

Well, that's the end of my first tutorial and Thank You for it. I hope it is a help to you. My next tutorial will be ready some time soon, so look out for it!! Any questions??? E-mail me here!

dandeman2k

© Daniel Marcus 2002


Mover Class Reference

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Mover | AssertMover | AttachMover | ElevatorMover | GradualMover | LoopMover | MixMover | RotatingMover
Introduction

I would first like to point out that this reference is aimed directly at level designers, and is not intended as a guide to the UnrealScript behind these objects. However to learn more about these objects I did frequently delve behind the scenes. So if you wish to converse about the script then feel free to e:mail me or catchg

First a bit of jargon:

  • Actor: any object within the game, including brushes, triggers, weapons and players
  • Pawn: any moving creature, including monsters, players and bots
  • Player: just real-life players
  • ScriptedPawn: basically just monsters
  • Touch or Bump: means this mover is triggered by a pawn running into its collision cylinder (formed from the collision radius and collicion height)
  • Event: some movers use the Event field to trigger another event
  • Tag: the name of the move
Each trigger has a number of keys next to it to signify a number of things:

TC: triggered by pawn contact

TG: triggered by another trigger

Mover

This is the basic mover from which all other movers are descendants. This means that if you understand this actor then you only need to understand the differences between this and other movers. Therefore this bit is going to be long.. ;-) (p.s. the first bit here is available in 20 other tutorials and covered in more detail with pictures, so if this isn’t much help to you I suggest you try reading some of them before continuing).

To create a mover:

  • Create your mover with textures etc.
  • Copy to active brush (the red one) by either intersecting a number of other brushes, or right-clicking on a brush and choosing Copy polygons to brush.
  • The click on the Add Mover button (as someone said, it looks like a marshmallow with arms).
  • To select a different type of mover (explained below) you must select it in the class browser before pressing the Add Mover button.
  • You should now have a purple brush. This is your mover.
  • n.b. make sure you reset the scaling on any brushes you use (or transform permanently) else players will fall through your mover.

The mover has the following states:

TriggerOpenTimed

When triggered the mover will move through its keyframes until it reaches the last one, stay open as long as the StayOpenTime variable and then return the the first keyframe.

TriggerToggle

When first triggered the mover will open. When it is next triggered the mover will close

TriggerControl

While the mover is being triggered (i.e. an actor is within the collision radius of a trigger) the mover will be opening. As soon as the actor moves from within the trigger radius, the mover is un-triggered and will close again.

TriggerPound

This opens and then closes repeatedly while the player is triggering it. The time between opening and closing is actually specified by the OtherTime property and StayOpenTime is the time between closing and opening again.

BumpOpenTimed

When bumped it opens, waits as long as the StayOpenTime parameter and then closes again.

Also the BumpEvent is triggered, and if the bumpee was a player then it will fire the PlayerBumpEvent as well.

If bTriggeredOnlyOnce is true then the mover will stay open after being bumped.

BumpButton

A bump button will open when bumped.

Also the BumpEvent is triggered, and if the bumpee was a player then it will fire the PlayerBumpEvent as well.

If it triggers another mover then it will stay open until that mover has closed (or in the case of a triggercontrol until it has swapped state). Infact whatever it triggers it will then usually wait until they have finished what they where doing.

If bTriggeredOnlyOnce is true then the mover will stay open after being bumped.

What a mover has finished opening it will trigger the event specified by its Event property. When it starts closing it will untrigger this event. (N.B. with the exception of the TriggerPound state which does not trigger this event).

Parameters:

MoverEncroachType:

describes what happens when something (like you) gets in the way of the mover moving. The default is Return. The others are Crush, Stop and Ignore. Return returns the mover the the previous keyframe. Stop stops it, never to go again. Ignore simply keeps it going. Crush means it makes small up down movements until you get out of the way.

EncroachDamage:

amount of damage done when a pawn is hit by a moving mover (whatever above is set to).

MoverGlideType:

whether the mover moves with a slow acceleration or moves linerly.

BumpType:

what classes can bump trigger the mover. Can be either player, pawn or any.

KeyNum:

current keyframe the mover is at, and the one it starts at in the game

NumKeys:

total number of keyframes the mover has

WorldRayTraceKey:

raytrace the world as if the mover is at this keyframe (used for lighting)

BrushRayTraceKey:

raytrace the brush as if it was at this keyframe (used for lighting)

MoveTime:

time taken for the mover to mover from one keyframe to the next

StayOpenTime:

amount of time between the open and closed states (apart from the TriggerPound type where it is the time between each Open and Close cycle)

OtherTime:

amount of time between the open and closed states for a TriggerPound mover

DelayTime:

pause once triggered or bumped before opening.

bTriggeredOnceOnly:

go dormant after first trigger

bSlave:

true if this mover is a slave to another mover. All movers with the same Tag are grouped together and follow the exact movements of the only one without bSlave as true, relative to their own base keyframe.

ReturnGroup:

default to the same as Tag. All members of this group ‘encroach’ together for return and stop types of encroach. If one member of the group is encroached then they should all act as if they have just been encroached. There seems to be a bug in the return type where the group doesn’t react the first time. This can mean that the other members end up out of sync with the leader. (I can’t explain it very well but here is a sample map TUT-Movers-ReturnGroupBug.zip)

I have to confess to not being able to get the above two too work to my satisfaction. Maybe it’s a bug in the script (I think it might be) or maybe there is some setting I’m missing out I don’t know but the linked movers frequently got out of sequence. Have any ideas… e:mail me.

bUseTriggered:

is triggered if a player tries to ‘grab’ the mover (the ‘G’ key in Unreal, never used it myself).

bDamageTriggered:

whether taking damage triggers this mover.

DamageThreshold:

amount of damage to take before it is triggered.

bDynamicLightMover:

If true then the lighting of the mover changes as it moves through the level. Obviously a bit of a memory hog though!

PlayerBumpEvent:

optional event when a player bumps the mover (BumpButton and BumpOpenTimed only)

BumpEvent:

optional event when any valid ‘bumper’ bumps the mover (BumpButton and BumpOpenTimed only)

OpeningSound:

plays when mover starts opening

OpenedSound:

plays when mover finished opening

ClosingSound:

plays when mover starts closing

ClosedSound:

plays when mover finished closing

MoveAmbientSound:

Optional sound to play when moving

N.B. don’t make the mistake of setting a looping sound in any of the first four sound slots, as they will keep playing forever!

[^Top]
AssertMover

I shall paste the comments from the code here and then explain the parameters:

// A mover which keeps opening as long as the instigator stays within

// the trigger's radius. If the instigator steps out, the mover will

// stay in it's current position for WaitUnAssertTime time, and then

// close all the way back to the beginning. If the bTriggerOnceOnly

// variable is true, once it reaches the last keyframe, it will

// stay there forever if bOnceOnlyStopOpen is true, or it will go back

// to the first frame (after waiting for StayOpenTime) and stay there

// forever if bOnceOnlyStopOpen is false. If bTriggerOnceOnly is

// false, when it reaches the last keyframe, after it waits for

// StayOpenTime, it will return to the first keyframe, and the

// entire process will be repeatable.

// Note: When the last keyframe is reached, Event will be called. M.

You must use the new AssertTriggerOpenTimed initial state for this to be of use.

However if normal states (such as TriggerOpenTimed) were used then the OpenTimes and CloseTimes arrays would still be used.

Parameters

OpenTimes[6]:

move times for six possible open keyframe moves.

CloseTimes[6]:

move times for six possible close keyframe moves.

bOnceOpenStayOpen:

if true and the final keyframe has been reached then it will stay there forever.

WaitUnAssertTime:

the time to wait in an open postion before closing. You could however trigger it again in the mean time and continue the opening process.

[^Top]
AttachMover

Identical to a normal mover but with one extra parameter, AttachTag. All actors with a Tag the same as this AttachTag will move as if they where standing on the mover. I would like to say that I have had problems keeping everything in sync when the mover is encroached but apart from that it works fine.

Useful for attaching lights to the give good effects.

N.B. You must set the following properties in the Advanced section of whatever it is you want to follow the mover:

bMovable=True

bStatic=False

bNoDelete=False

Parameters

AttachTag:

tag to match all other actors to this mover

[^Top]
ElevatorMover
This mover is used with the ElevatorTrigger (as well as the CodeMaster and CodeTrigger, see Triggers Reference), giving it the ability to be sent to a specific keyframe. Rather than moving from keyframe 0 to the final keyframe and back again you can trigger it to move to a particular keyframe (in much the same way as an elevator works ;-)
Parameters

No additional parameters.

See ElevatorTrigger for details on how to trigger it.

[^Top]
GradualMover

Allows the mover to be gradually triggered, i.e. the first trigger opens it so far, the next trigger opens it a bit more and so on, until the final keyfraem is reached.

This is the first state GradualTriggerOpenTimed. The other two

Parameters

OpenTimes[6]:

MoveTime for the 6 opening moves

CloseTimes[6]:

MoveTime for the 6 closing moves

Tags[6]:

tags which will trigger each stage, initial trigger in Tags[0]

Events[6]:

events to be triggered when each open is completed

[^Top]
LoopMover
Once triggered this mover will continue moving through its keyframes and then back to keyframe 0 until it stops being triggered. A TimedTrigger (UT Only) is a good trigger to use if you wish to trigger a loop mover at the start of a game. Either that or a normal trigger with a large collision radius, so the mover only moves when it can be seen.
Parameters

No additional parameters

[^Top]
MixMover
This is a combination of ElevatorMover, GradualMover and AttachMover. It has an attachtag which you can attach anything to it and apart from that has the same states as a GradualMover. It also has an ElevatorMover state but this cannot be triggered from any current trigger as they all require an actual ElevatorMover class object which this isn’t.
Parameters

See GradualMover and AttachMover

[^Top]
RotatingMover
Rotating movers are mover which when triggered rotate, according to their RotateRate under RotatingMover.
Parameters

RotateRate:

Roll, Pitch and Yaw rate of the rotate. Will me dependant on the Tick rate of the game so reliable roate speeds are not possible.

[^Top]


BB Drac - Unreal Tournament UED2 guide Teleporters

Teleporters

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Teleporters are used to transfer players instantly from one
place to another.

Screenshot

In the picture above you are able to see two teleporters.
The left one is a standard teleporter and will not be visible in the game.
The right one is a "Visible" teleporter and is for those who don't want to create
facy gfx or don't need the teleport to stay unseen.

The first teleporter is found under "NavigationPoint" in the actor browser, named "Teleporter".
Under the "Teleporter" you will find "VisibleTeleporter".

There is a few properties you can change:

Property | Specific
+Collision |
CollisionHeight | The area this teleporter will cover.
CollisionRadius | The area this teleporter will cover.
+Events |
Tag | This is the name of this teleporter.
+Teleporter |
bEnabled | Enable/disable the teleporter for usage by players.
bChangesYAW | Alter the direction the player face when teleporting.
bChangesVelocity | Changes the moving speed of the player teleporting (destination).
URL | This is the target destination teleporter (teleporter tag).

Creating teleporters:
To create two working teleporters you must alter the correct properties for both.
First you must add a name/tag to each teleporter.
The first could be "tele1" and the second "tele2".
That is only the name. We also need to connect them.
In the teleporter named "tele1" you must add "tele2" to the "URL".
Vice versa for the second. "tele1" in "tele2"'s URL.

If the "URL" stays blank the teleporter will work as a destination only.

If more than one teleporter has the same name/tag players will arrive at a random one.

 Changing players direction when teleporting:
To make sure that players face the correct direction when teleporting you must
enable "bChangesYAW" on both source and destiantion teleporters.

The source teleporter should face the direction you want players to enter from
(and the direction players face when this is the destination).
The destination teleporter should face the direction you want players to
face (and enter when it works as the source).
Confusing? Well, don't mind it too much until you have tested it a bit.

 bEnabled vs URL:
Both options "bEnabled" and "URL" can be used to prevent players from using a
teleporter.
If you leave the "URL" blank the teleporter will not work for players at all.
It will work as a destination teleporter though, as long as another teleporter
has its "Tag" in the "URL".
The "bEnabled" (true or false) will also enable or disable the teleporter for
players. It will still be able to work as a destination teleporter.
If a trigger is connected with the teleporter the "bEnabled" will toggle between true
and false, giving a better control if the teleporter is supposed to allow players to
use it or no.
Teleporting to other levels:
Teleporting between two different maps is pretty much the same way two regular
teleporter works.
First of all you need two maps.
Each map should contain a teleporter so that you are able to actually get to
the destination teleporter.
The URL syntax you must use is "[mapname]#[teleporter]?peer".
'mapname' is the name of the map and 'teleporter' is the destination teleporter.
'peer' must be present as it tells the game to open a new map.

So in two maps called "castle.unr" and "gate.unr" you place one teleporter
in "castle.unr" and one in "gate.unr".
If the castle teleporter is called (event tag) "castle_tel" and the gate
teleporter (event tag) "gate_tel", the correct teleporter URL syntax to teleport from
gate.unr to castle.unr would be "castle.unr#castle_tel?peer".


BB Drac - BB Drac - Unreal Tournament UED2 guide Teleporter Zone

Teleporter Zones

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Teleporter zones is mainly used to teleport players from one "area" to a specific
location.
This is a bit different from normal teleporters as they teleport from location to
location.

In certain situations this can be very difficult to achieve as you might not
be able to exactly calculate the position of a player.

Teleporter zones is very good to use in levels where players might fall
of a ledge and you want them to be "moved" to another location, instead of killed.

Here is how you could do it.

Create a somewhat large room (256x768x768) and add light and texture
to it.
Also create a very deep shaft (768x256x256) and place it at the bottom of this room.
(Do not light this shaft though).

Screenshot

When done create a sheet 256x256 in horizontal and place it fairly close to
the bottom of this shaft (if problems arise try to move this bush up abit).
Press the "Add special brush" and select "Zone Portal". Just press "Ok".

Screenshot

Now open the actor browser, expand "NavigaionPoint" and "Teleporter".
Select "Visible Teleporter" and place two of them somewhere inside our first room.
(The reason we use visible teleporters here is just to demonstrate how things
work. Normally you would use standard teleporters.)

Screenshot

Also expand "Info" and "ZoneInfo". Select "TeleporterZone" and place it in the centre
at the bottom of our shaft.

Screenshot

Open the properties window for the "TeleporterZone" and adjust the "TeleporterTag"
under "TeleporterZone" to "back_up".

Open the properties for one of the teleporters.
Under "Events" type "back_up" in the "Tag".
Under "Teleporter" and "URL" type "home_again".

Go to the other teleporter and open its properties.
Here you Change the "Tag" under "Events" to "home_again".
Under "Teleporter" you must set "bChangesVelocity" true.
(Otherwise you will still take falling damage if you fall too far).

Now everything should be working.
Add a playerstart (in the top room) and rebuild the level.
Try and see how nice everything works.

When you test this, you will see that one of the teleporters work perfectly
ok. If this had been a functional level you would probably want to place
this teleporter inside the teleporter zone to make it unreachable for
players.
The other teleporter reports an error (could not find the destination).
That is simply because we used a visible teleporter, don't mind it.

In reality we have told the teleporter-zone to use the first teleporter as the
source teleporter which teleport us to the other teleporter.


Unreal Editor Maximum [unrealism.com/unrealedmax] -Teleporters, Translocations and Jumpspots

TELEPORTATION EFFECTS, TRANSLOCATIONS & JUMP SPOTS

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

Teleportation effects are just that :). Since translocator devices in Unreal Tournament are just "personal teleportation" devices I figured they should be on the same tutorial. Jump Spots show the bots which places can be reached with a jump boot or a normal jump and how to jump to that place.

TELEPORTATION EFFECTS:

This tutorial is more about teleportation effects than about the how and why of teleportation's. What is this teleportation effect I'm talking about? - two maps that use this is CTF-Facing Worlds and the assault map Overlord (remember the foxholes). Well to achieve that effect its a simple process (hey I'm wondering if that's the reason that I wrote the tutorial in the first place). The effect is achieved by simply taking a decoration from under classes menu and changing its texture and draw type. Here's how to do it:
1. Create a room 1024x2048x2048 or something around that size so that we you can do the whole tutorial in one map without having to create a separate map for each part of the tutorial.
2. Choose classes from the browser on the right. Expand Decoration| ut_ decoration and choose barrel1. The choice of the decoration to use for the effect is up to you, but I usually use barrels or the utflare or torch flames - you can use something like a fighter just use any deco :). Add one barrel on either side of the room. Change the texture on one wall to something bizarre or out of sync so that you can identify that it works - you'll be able to make out which one you went into and which one you got out from.
3. Got to barrels advanced properties (or whichever decoration you used). Then under display you need to set the following parameters:

(a). First and most important choose a texture for the teleporter effect. I would suggest the Worm files (Worm 3A,B,C, etc.) from the SpaceFX texture package or the from the HubEffects texture package. I used the worm3a from SpaceFx.
(b). Once you have chosen a texture hit the use button next to the line that says texture. Don't touch the mesh settings.
(c). Under style choose STY_Translucent so that you are able to see through the effect.
(d). Under DrawType choose DT_Sprite. If at a later date you find that you are not getting the effect that you wanted this is probably the step that you screwed up.
(e). Next set DrawScale to around 1.5. the size is up to you but don't make it too small. Also set ambient glow to around 100.
(f). bUnlit - True, so that it reflects all the possible light from around it.
That's the end of the teleportation effect. You can leave all the other default settings in place.
4. You should place light right on top of the barrel that has become the teleportation effect according to the color scheme. This makes it look funky. For example if you used the red worm you could just place a light right on top of it and change LightColor under its properties to LightHue 0 and LightSaturation 0. Take a look below to see what I mean.

5. As you can make out from the picture above I've placed a teleporter right smack in the middle of the former barrel. Locate it under Classes|Navigation Point|Teleporter (don't expand it just add in a plain teleporter). Place one more in the middle of the second barrel that you should know by now how to make into a teleporter effect. Set the tag (under Advanced Properties| Events|Event) of the first teleporter to 1 and the tag of the second teleporter to 2. Then under the advanced properties of the first teleporter, expand Teleporter and in URL put 2. For the second teleporter set the URL to 1. This way when you step into one you will step out of two and if you step into two you will step out or be taken to one. Remember that they can be anywhere in the map, i.e. 1can be at one end and 2 at another end of the level. Under collision play around with the radius to get the effect that you want.
6. Place in a Player Start from under navigation point. Since you've placed all your lights just do a quick rebuild of lighting and geometry and viola you are ready to go. Here you can see my final level:

NOTE: You can locate something known as the visible teleporter from under teleporter. You just need to place this in your level and set the tags and their URL's no need to bother about textures, DrawType, etc. - just add it in and set URL's and you are off and running - a totally preconfigured teleporter. I personally don't like using these, except in team games as I feel the do something to the level that doesn't gel well with me. But if you remember the DM-Gothic map which uses this it doesn't really detract that much from the feel of the level. So it depends on you but I feel these teleporters are far better. To drive home this point I suggest you follow this link to cliffyb's site and read what he has to say about DM-Unreality][ which uses teleporters. Well that should be proof enough that using teleporters in death match is a bad idea.

BOT TRANSLOCATION :

Sure you can use the translocator however you want, but how do you let the bots know they should use the translocator device to reach a certain area. Lets find out how:
1. Add a room to the side of the first room that was created before if there is not enough space and connect the two rooms. We want to make a high ledge and make the bot use the translocator device to get onto the ledge. You must remember though that the bot will not make a translocation simply - there has to be reason for it. So when you make the ledge put the only weapon (from Classes| Inventory | Weapon) on that ledge. Ok after you finish creating a ledge (around 256x256x1024) by adding it into the room place the only weapon (the only item in this level for that matter) on the ledge so that you can observe the bot doing the translocation.
2. Expand Navigation Point|LiftCenter. Under that you will see an item named translocdest (translocation destination). This must be placed where you want the bot to aim and shoot the translocator device. Place this on the ledge next to the weapon. Under translocdest's advanced properties expand LiftCenter you should see an entry for LiftTag give it an unique name like translocation1. That's all you need to do for the translocdest - no need to touch Events|Tag or anything.
3. Still under Navigation Point locate LiftExit and place one next to the transloc- dest on the ledge and one on the floor from where you want the bot to shoot the translocator device. Under both their advanced properties expand LiftExit and set LiftTag to the same as the previous one in this case translocation1.
Hit F8 and when the rebuilder opens hit Paths Define under the lighting tab. Since there is no progress bar the only way to find out that its over is by clicking around. In the first person view, under the view menu check show paths. You should see the liftexit on the ground connected to the translocdest on the ledge by a blue line and the other liftexit on the ledge. The translocdest is on the left in the picture :

4. Place a second player start in the room. Locate pathnodes from under Navigation Pont and by using the first person view add in a line of them from both the player starts to the liftexit on the ground. Do a rebuild of geometry and lighting if you haven't done one already and under the lighting tab do another Paths Define.
5. When you open the level under practice session in Unreal Tournament go to the settings tab and check translocator. When you play the level you should see the bot rush and do a translocation to get onto the ledge.

JUMP SPOTS :

Jump Spots basically let a bot know that he can use the jump boots or impact jump to get to a previously inaccessible area. Its unlikely that if you place the jump spots at one end and the jump boots at another end that they will ever use it. Jump Spots can also be used normally in the sense that you can show a bot that a place can be accessed by a normal jump. For example if you have a series of ledges and below that lava and the only way to cross is to jump forward from ledge to ledge then you should use jump spots.

Jump Spots don't need to be explained that much they are just like transloc -dest so the same settings apply. (They are located in the usual place - Navigation point|LiftCenter). That is you would place a JumpSpot on the ledge and next to it a lift exit and on the ground another liftexit and use the same settings as translocdest. You should also place jumpboots nearby. This is for jump boot settings. As I mentioned before we can make the bots do an ordinary jump in the same way. All the previous settings apply here the only thing you need to do is under the jumpspots advanced properties|jump spot set bImpactJump to true. Only in the case of normal jumps without jump boots should you use this setting - it basically tells the bots they can attempt the jump without boots by using the impact hammer. Another example is that if you have a ledge not really high but not really low either and some stuff on it the bots will get confused or wont use it unless you use a jumpspot. As usual do a paths define and check it out. That's it for this tutorial.


deCyber Build Section

Teleporters and portals

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Downloadable files : Portals.UNR

Contents

1) Teleporters
2) Using teleports between levels
3) Warp Zones (portals)

Introduction.
I bunched Teleporters and WarpZones into one tutorial because both of these do similar things. Warpzones allow you to pass smoothly from one part of a map to another. They also allow you to see what you’re going into before you get there! Teleporters don’t look as neat, but they have the advantage of being able to transport you not just somwhere else within your level but to a whole new level altogether. First I will take you through teleports and then through WarpZones.

Teleporters

First we’ll look at a simple teleport that transports you from one room to another:

1) Create two very basic rooms with light in them and add a player start. (try and make them look different from each other somehow)

See some of my other tutorials if you’re not sure how to do that

2) Open the "ActorClassBrowser" and then open out "Navigation Point". A list of items should appear. Choose "Teleporter", and add one to each of your rooms (You can also use visible teleporter if you like). These are directional, so when someone comes out through one you can choose which direction they will be facing when they arrive. Just click on one and you should see an arrow stick out from it. Hold down the CTRL key and the right mouse button and when you move the mouse you should see the arrow move too. As teleport actors are invisible
when you play the level, it may be useful for you to put a boulder or some other decoration next to it so that you know where to head when you test your level (unless of course you're using the visible teleporter).

3) Both teleporters can act as either 2-way or 1-way its up to you. Click on one of your teleporters and press F4 to bring up its properties box. Under the section called "Teleport" you will find a field called "URL". This is where you want your player to end up when they enter your teleport. Type "Ping" in this field. Click on the teleport in the other area and give the URL field the name "pong".

4) You’ve now told both Teleporters where you want them to send people, but now you need to tell UnrealED where "ping" and "pong" actually are. In this case, we will make the teleports jump back and forth to each other. In the same way as most other actors in UnrealED, your teleporters have a "tag" so you can label them. Click on the teleport which has "Ping" in the URL field, then bring up the property called "Events" and type "Pong" in the "Tag" field. Likewise, the other teleport with "Pong" in the URL field, must have "Ping" in its "Tag" field.

If this sounds confusing, check out the map that comes with this tutorial

5) That’s all there is to it. Test your level and you should be able to run back and forth between each room as often as you like.

Using teleports between levels

1) If you're making an SP map you can use teleports using the same method to transport your player from one level to another. All that needs to be different is the name of the URL. Create two very basic levels. In each level build a simple room and do the same as you did in the previous example. Call one level "A.unr" and call the other level "B.unr". Put a player start in "A.unr" (it could be in B.unr if you like).

2) Both levels should contain a teleport. (just as the previous example had two rooms, each containing a teleport). In the level you call "A.unr" choose your teleport and type "Pong" in its "Tag" field. The formula for URL fields is "mapname#teleporter tag?peer". So, in the URL field for this teleport type, "B#Ping?peer". (Peer, tells Unreal to open a file). Now save your level.

3) Open up your other level called "B.unr". Bring up the properties for the teleport in this level. Type "Ping" in its tag field and "A#Pong?peer" in its URL field.

4) Once you’ve saved it, test it by playing A.unr and then see how you can
go back and forth through the two levels.

Warp Zones (portals)

This is where it really gets sticky! These are like teleports, but as I mentioned above, you can actually see into the other area of the map you are about to run into. They don’t, however, jump between levels. If you’ve not been editing for long, and you’re not too familiar with "zones" I strongly suggest that you become familiar with the tutorial on ZONES first, it will give you a better understanding of this particular tutorial. These are fiddly, but well worth it when you see the end result.

1) Create two rooms in the same way as you did for your teleporters. Make they are nice and large, say 1024 x 1024 x 1024, so that you have plenty of room to run around in there. Add all the usual stuff like lighting, playerstart and game info. Make sure that both rooms look different so you can see the full effect of the Portal you’re making.

2) Now you need to create some sort of portal gate that your player can fit inside (create one for each room). For this exercise we will use straightforward blocks. First, add a brush inside your room 292 high x 192 x 192. Then subtract another block from it sized 256 x 128 x 128. Rebuild and save. You should see a hollowed out cube in your room.

3) Now you need to turn this portal gate into a zone of its own. To do this you need to add a sheet to your cube so that the opening is completely covered. Right click on the sheet icon which in your left-hand toolbar. In its size properties change it to 264 in the height field and 136 in the width field. Then set it to X axis (so that it covers the entrance of your gate, it may be Y axis if you’ve faced them the other way). Line this brush up so that it covers the entrance to your gate with no gaps, as close to the edge as you can (set grid size to 1 or 2 if you want it really close).

4) Now click on the "Add Special Brush" icon. A box should appear. Where it says "prefabs", set it to "Zone Portal" and click on "OK". Now rebuild and save. In your 3D view choose "Zone/Portal view" from the end icon in the 3d view menu bar. Both of your gates should be a different color. Your grid views should look something like the pictures below.

TOP VIEW SIDE VIEW

5) You’ve probably noticed that there is also a strange looking cube with a question mark inside the gates too. This is what you need to add next, this is the "WarpZoneInfo" actor. Choose it from the "ActorClassBrowser" under
"Classes/Info/ZoneInfo" and add this to the inside of each of the Portals.

6) Select each one of the "WarpZoneInfo" actors and press F4 to bring up its properties. This is similar to the teleports. You have a destination and tag. If you want a one-way portal, only give one of them a destination.

Under the field called "OtherSideURL" type "Ping", and in the field called "ThisTag" type "Pong".

In the other Portal type "Pong" in the "OtherSideURL" field and "Ping" in the "ThisTag" field.

Rebuild and save it. If you test it now, you should see the awesome effect of looking through
a portal into your other room.

You can now run backwards and forwards through them.

7) If you want to make it look even more interesting, try adding another sheet, one unit in front of the Portal sheet as a "Water" sheet and then give wavy, transparent properties. Also add an ambient sound to give it that freaky feel.

And there’s your portal.
If you’re having trouble try looking at the map that comes with this tutorial.

TIP: Don't try and make a portal that looks out into a sky area. The engine has difficulty showing you stuff through two zones!

EZkeel
(Simon West-Bulford)


Creating a simple Teleporter

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers :

Creating a Teleporter

Forward:

These are extremely easy to use , but please PLEASE PLEASE DO NOT OVER-USE THEM!!!! I don't even want to mention my first map (DM-Teleworld....i'll leave it to your imagination to work that one out...).

Content (or whatever):

Now this is so stupidly simple that i shouldnt even bother writing it.....but i will. Here goes : I'm guessing that you already know how to make a basic level and have one ready because i'm not gonna explain any of that (refer to my other tutes if you dont know how to make a level).First of all, find a place where you want to shove these little doohickeys then go to Actor Classes>Navigation Point>Teleporter>Visible teleporter then right click and select "AddVisibleTeleporterHere".There ya go!
Oh yeah , you want it to work dont you......Well go to the properties of it and give it a tag, (Events>tag) this can be anything you want , so go ahead and be creative.
Then add in another telepoter somewhere give this a different tag , then (this is what makes it work) go to properties>Teleporter>URL and type in the tag of the first teleporter and vica-versa with the other one. These will now transport you in and out of both of these.BOOYA! Your done.

If you want to get creative you can have one way teleporters (tele1>url=tele2 , tele3>url=tele2 etc) or you can have like 50,000 of them (the mistake i made) and you can also do heaps more stuff , all you have to do is experiment.

I'll tell you one thing that you can do though: You can make Teleporter a got to teleporter b, but not vica versa. This is a pretty cool thing to do. All you have to do is not give teleporter b a url and make it invisible, that way, they can get to location b, but not back to a again! Experiment ahoy! I'll leave the rest up to your imagination.

About the tute: I decided to write some tutes because of the fact that nearly every tut on the net has been written for UEd1 and that really pisses me off..... sorry about that , but that's the truth. I apologize for the use of so many brackets , but that's just the way I "write".

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Teleporters

Teleporters - Quake 2 style

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

I was recently asked how to create the famous "Quake 2" style Teleporters.

Fair enough. It"s easy here is how you can do it. I will not go into detail here on how to create the shapes of teleporters, or how to create the texture that I have used here, but only deal with the Real Fun stuff. If you really want to know, I used a simply cone for the basic shape, the floor lofter for the base, and the "fire Engine" for the texture. there, that"s about as detailed as that"s going to get. The good stuff follows.

You will need a really basic understanding of the editor here, as it"s so damned simple =) First make two rooms. Do noconnect them in any way. Make sure that they are separated from each other completely. I have made these rooms 256x512x768 but"s it completely up to you. I have made the two room to look completely different, but once again, tah"s up to you. It might be a good idea to try to make a teleporter series that sends the player to places that seem identical just to be really confusing, but that"s another story...

Locate the place in the 3D voew where you want the first teleporter to go, and open the "Classes" menu. Open the "Navpoint" subclass, then choose "Teleporter" (Coincedence? I think not... ;-). Now you most likely be automatically moved to the "favorite" thing, but select the normal teleporter again, and place it in the the 3D view where you want it to go. This will be the first teleporter that your player sees. Well, actually if you are placing these into your level (and not making a little tutorial level then it makes no difference, otherwise it will be the first one that the player sees). Ok, That done, open the advanced properties of the teleporter (right click on the icon) and select the "Event" tag. name it "One" under Tag. This will name the teleporter for other teleporters to link to.

Ok, that was easy wasn"t it? Now go to the place where you will have your second teleporter and place it in, just like you did the first. This will be where the first teleporter sends the player when they walk through it. Now, in the "Event>Tag" entry, type in "Two". Sheit, I am so damned creative with names for teleporters eh? Hehee. This time, when you have entered the tag (the name of the teleporter) also open the "Teleporter" menu from the bottom. Right at the bottom there is a entry names URL. This has got nothing to do with the net, but actually refers to the teleporter that the player will be sent to from this one. In the feild type in "One".

Now, go back to your first teleporter and in the same field (the URL entry under Teleporter) and enter "Two" as the URL. This will create a simple loop between the two. When the player walks into one, they will be sent to the other.This is the most basic of teleporters. Ie, one send to the other, and vise-versa. It will let you make nice teleporters. The following will explain some of the more complicated things (although still quite easy) that you can do with teleporters.

Pathed Teleporters : I don"t know what to call them, so I made up that name, but this will simply make a chain of teleporters, rather then just having the two that send the player back and forth. To make a "line" of teleporters, all you will have to do, is to create a third (or fourth or fifth etc etc) teleporter, and change the URL corresponding to the teleporter that you want it to go to.This will then send the player to a different location if they try to "weasel out" and go back to where they came from. Nice if you have a particularily nasty monster near a teleporter, and the player tries to flee back to where they just came from. Nice to send them to a dark place that has yet another monster there. ( I think that I am too nasty sometimes.... Oh Well. Sue me =)

Single Destination Teleporters : You can make a whole heap of teleporters all have the same destination. All you have to do is to change their respective URL"s to the same tag of a teleporter. This is a good idea to do, if you want a series of "one way" teleporters. This will allow you to have a teleporter go to another, and then send the player to a destination if they try to run back through the teleporter that they just came through. A nice deadly trap comes to mind...

One Way Teleporters : This is really simple. All you have to do, is to make the teleporter"s URL entry blank. This way a player will not be able to run away from whatever you have in the new part of your level.

See I told you it was really easy. That"s all that I can think of to place into the tutorial right now, but if you have further questions then email me.


Wolf's Tutorial Eleven - Triggers

Wolf's Tutorials: Triggers

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Introduction:

This is an intermediate to advanced tutorial. If you are new to UnrealED then please see my tutorial page for links to Basic Tutorials to get you started.

Triggers

We are going to discuss (and learn to use) various kinds of triggers in this tutorial. We will not cover all triggers. This tutorial is designed to get you familiar with how triggers work and their various properties. You will learn how they work and a few different type of triggers you can deploy for various effects. You can use what you learn here to figure out other kinds of triggers.

Basic Trigger

For a trigger to work you need a couple basic things. An Event and a Trigger. There are two properties that are ESSENTIAL for triggers. They are found under Events (any any actor Properties window). They are Event and Tag.
You can think of the Tag as the name of the actor. This Tag is the "name" the trigger calls to send the actor into action.
The Event is the where you put the Tag you want the trigger to call.

Simple Example

Switchable Light
Let's start by making a small room (256 sq). Add a PlayerStart in one corner. In another corner add an object that might be a switch. Add a trigger (Expand Triggers and choose the Trigger with the big minus sign next to it --see image below) in the corner in front of your switch looking texture.

Now in the Browser go to Classes. Expand Light and choose TriggerLight (the first one). Now add the TriggerLight in the center of the room, near the top.
Now we have all the actors, we just need to set it up.
First, set the Tag (under Events) of the light to something unique, like LIGHT1. Now open the trigger properties and under Events set it's Event to LIGHT1 (or whatever tag you gave the light). Now wee need to do a couple more things to the light. First open the TriggerLight properties window. Under TriggerLight make sure bInitiallyOn is set TRUE.

Now under Object/InitialState set it to Trigger Toggle. This will turn the light on or off as the trigger is activated.
Okay, that should do it. Now Rebuild and then run the map. When you walk to the corner where the trigger is the light should go off. Take a couple steps back and then forward again and it should come back on. Basically, whenever you activate the trigger it will toggle the light to on or off.
Breakdown:
The EVENT in the trigger properties tells the trigger WHAT to activate. The TAG of the light names it so the trigger can activate it. Always make sure the Tag of the actor you want activated and the Event of the trigger you want to activate it are the same. The light property set to initial on (bInitiallyon=True) can be set to off and then the trigger would turn it on). The Object/InitialState of the light is set to toggle so that it will switch back and forth between on and off each time you activate it.
Explore:
Try setting the InitialState of the light to other settings besides TriggerToggle.
Try TriggerControl: This should make the light go out whenever you are in proximity of the trigger.
TriggerTurnsOn and TriggerTurnsOff are pretty self explanatory.
TriggerPound doesn't work on a TriggerLight actor.

Trigger Properties

So, all the settings that control the light we set with the light actor. Doesn't the Trigger itself have any properties we can set? Glad you asked.
Yes.
There are a few things with the trigger you can set as well. Open the trigger Properties then Expand Trigger.

 TriggerTypes
Look at the TriggerType

This defines what activates the trigger. TT_ means TriggerType to the engine.
The default is TT_PlayerProximity. This simply means whenever the Player is within the Proximity of the trigger--see Proximity below).
TT_PawnProximity means only pawns (any pawns) can activate the trigger.
TT_Classroximity means only a special class (defined in ClassProximityType) can activate the trigger.
TT_AnyProximity means any of the TT_ types can activate the trigger.
TT_Shoot means you have to shoot the trigger to activate it.
Proximity
This is how big the the "area" of the trigger is. You set this under Collision/CollisionHeight and CollisionRadius. These should be pretty self explanatory.
InitialState

Under Object/InitialState you can set the "state" of the trigger. Your choices are None, Normal, OtherTriggerTurnsOn (or Off), OtherTriggerToggles.
Normal is just that. The trigger works when activated.
None will deactivate the trigger altogether.
OtherTrigger settings should be pretty evident what they do.

Trigger Settings
Under Trigger (where we found the trigger types) you will see a few more settings that you can adjust.

bInitiallyActive A True/False toggle. Setting it to False means something must activate the trigger (another trigger for example) for it to work.
bTriggerOnceOnly A True/False toggle. If set True it will only work ONE time.
ClassProximityType Used to define the ClassProximityType under TriggerType
DamageThreshold How much damage you must inflict on the trigger when it's type is set to TT_Shoot.
Message The message to display when trigger is activated.
RepeatTriggerTime Time between the trigger repeats
ReTriggerDelay Time delay before trigger can be re-activated.
TriggerType (see TriggerTypes above).
Other Triggers Classes
If you expanded the Triggers tree in the browser (which you had to to find Triggers) then you saw lots of other kinds of triggers. I will not explain them all but here are some popular kinds you may want to try out. An (!) means It is defined in more detail below:

CodeTrigger (see ElevatorTrigger) Counter Must be triggered a certain number of times before sending the trigger info to it's event
Dispatcher (!) Is triggered itself then activates a user set sequence of events with optional delays
ElevatorTrigger Hmmm...I wonder what this does? I'm saving this for a future tutorial!
FatnessTrigger When activated sets the fatness of an actor from one state to another.
FearSpot Creatures will tend to back away from this area.
Jumper Creatures will jump in a specified direction when activating this trigger
MusicEvent (!) Where you specify and change background music
RoundRobin Everytime you trigger this it advances through a set of outgoing events
SpecialEvent (!) Receives a trigger message and sends out various "Special Events" depending on it's setting
StochasticTrigger Kind of like a dispatcher but you set certain special events to occur
TranslatorEvent (!) Where you set the "pop up" Translator Messages
-Trigger Basic Trigger
ZoneTrigger Activates/deactivates zone properties (only bGravityZone works).
TriggeredDeath Kills that which activates it.

Dispatcher

Dispatchers are used to trigger multiple events. You can delay the out put to create a "scripted sequence" of events.
You can use it to do all sorts of things from one trigger with various delays. You could have it open a door, turn off (or on) a light and play a sound then wait a second and shut the door, toggle the light and play a different sound. You can do lots of cool "scripted events" with these handy triggers!

OutEvents set the sequence of events you want triggered and in what order.
OutDelays set the delay between the events.

MusicEvent

Here is where you set and change the cool Unreal background music.

Song and SongSection are the two settings you will use the most Song picks the song you want to play (under Music in the Browser you can load the songs you want) SongSection is a setting of 0, 1, or 2 to set the mood of the song (normal, tense, action I think)

SpecialEvent

The settings under Object/InitialState determine what type of special event is triggered:

For the most part they are self explanatory (PlaySoundEffect, DisplayMessage, etc...) The particular settings for each type are set under SpecialEvent.

TranslatorEvent

This is where you trigger the messages that appear on the Translator.
The specific settings and the Message itself are entered under TranslatorEvent.

Other Ways to Trigger Events

Actor Triggered Events

There are other ways to trigger events besides actual triggers. The easiest and most common would be to set an Event to an actor such as a mover. If you specify another actor's Tag in the Event of the mover, when it is finished going through it's key frames it will activate the actor. For instance, let's say you have a door that is activated by a lever. Make a mover that looks like a lever. Make a door. Give the door a tag like "Door1" and set it's initial state to TriggerOpentimed. Now set the event of the Lever to "Door1" and when the lever moves it will activate the door.

BumpButtons

Bumpbuttons are cool ways to set one mover to activate another and not have all those red lines connecting them in your maps.
Make a mover that looks like a button (or whatever you like). Make another mover that this will trigger (like a door or something). Now give the door a unique tag.
Now under the button's InitialState set it to BumpButton.

Now under Mover set the Bump Event to the tag of the "door" you want it to activate. You can also set the BumpType (to player, pawn or any).

Now if the button is touched it will activate the other mover. You can also set the BumpEvent to a SpecialEvent's tag and activate a special sound or message or whatever. You can do lots of cool things with this one, too.

Tips

Anytime you want a single trigger to trigger multiple events use a dispatcher.
Anytime you want a "button" or "switch" (a mover) to activate something set it to a BumpButton.
Always double check your Tags and Events if something isn't working right. This is usually not set right when something fails.
You can check just what properties a trigger is affected by simply by opening the trigger's script (double-clicking it in the browser) and reading the comments (green stuff).
The way the trigger affects the event (toggle, control, etc,...) is set in the actor's Object/InitialState.
The way a trigger is activated is set under the Triggers TriggerType.

Pull The Trigger

Now you should have enough info to start triggering things all over your level. You should be able to trigger whatever you like now and set it off the way you want. Explore and play around with different types of triggers and their settings.

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


By

Basic Trigger Overview

By: Bostich

Assumptions

I'm working under the assumption that you already know how to make a Mover, or Moving Brush. If you don't, then please grab a copy of a tutorial on that or none of the following will make any sense. For this Tutorial I have included a map that has three triggers. I made the second Trigger by right clicking the Trigger and choosing Duplicate. The third trigger is a button, which is easier than a trigger, and included here because it's not worth a whole tutorial.

Triggers1 : Triggering Movers

I'm only going to cover how to Trigger Movers in this tutorial, otherwise it would go on forever. Okay, I also have no idea how most of the other triggers work. The important class for this tutorial is the Trigger -> Trigger class. As the name suggests, Triggers are used to activate properties of other classes, which means you must remember to edit the properties of both the Trigger and the Target. Triggers need some other object to interact with.

Making the Trigger

Let's add a simple Trigger to the room. Go to the Classes menu -> Triggers -> Trigger. Add a Trigger to your room. For the room provided I added the Trigger right in the path between the PlayerStart and the "Door", this way all you have to do is walk forward and you'll see the Trigger in action. There will now be a beautiful little Trigger Icon floating in space. Now go to the Trigger Properties by right clicking on the Trigger Tag (Seen above). Click on Events to reveal Events/Event and Events/Tag. Event is the pointer to the object you wish to act upon and Tag is the name an Event links to. If this is a bit confusing it will be made clear in a second. In the Trigger properties set Events/Event to 'Mover1'. Now go to the Mover Properties by right clicking on your Mover and change the Events/Tag to 'Mover1' if it doesn't already say this. You will now see a red line appear in all views. This red line is the logical link between your two actors.

Trigger Activation

Your Trigger is now linked to your Mover, but this is not enough. You must properly set the activation types for both the Trigger and the Mover. For this tutorial we want the door to open when the player moves towards it. In the Trigger Properties, look at the Trigger/TriggerType. You will see that it is set to 'PlayerProximity', which is what we want. Click on the right hand column to see what other types of events you can use to activate the Trigger. Now switch back to the Mover Properties and move to Object/InitialState. Click on the right hand column to bring up the states menu. The important states for us are the TriggerX states, which are as follows:

TriggerPound :- Causes the Trigger to rapidly move between states, good for squishy traps.

TriggerControl :- Causes the mover to change keyframes and remain until the player is no longer within the Trigger.

TriggerToggle :- Toggles the state of the Mover from one keyframe to another, for that open and closed look.

TriggerOpenTimed :- Causes the mover to open for its specified time the close. Time open found in Mover/StayOpenTime.

Set your movers state to TriggerOpenTime. If you compile and run your level you will now have a door which opens whenever your player walks into the Trigger location.

Button Triggers

Not big enough for a tutorial of its own, here's how to make a "button" Trigger. Make another small Mover. Change the Events/Event of your small Mover to the Tag of the "Door" Mover. That's it, pretty simple no?

Notes

1 :- Don't forget to add another Trigger on the OTHER side of your door, if you want to get back into the room. The first map I made I forgot this and whoops!

2 :- I suggest placing your Trigger no more than 64 off the floor, unless you want your player to be jumping a lot :)


BB Drac - Unreal Tournament UED2 guide Triggers explained

Triggers Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

To make 'things' happen at different times and situations you need to
create events.
The game engine use a simple system of tags and events which simply mean
that all objects that have the same tag as the event will be activated.

The triggering object will broadcast its event and all objects that have the same
in their tag will react on the action.

To create these events triggers are used.
There is alot of different triggers that work in almost every situation.

You do not need triggers to create events.
Most objects will trigger an event when specific conditions have been met.

The triggers are found under "Triggers" in the actor browser.
This is a list of different triggers:

Trigger | Specific
BioFear | Area feared by bots, determined by collision radius.
CodeTrigger | Will trigger event when a specific order of events been activated.
Counter | Triggers event when a number of events been activated.
Dispatcher | Triggeres multiple events with optional delays.
DistanceViewTrigger | A trigger that "tell" bots where to pay attention.
ElevatorTrigger | Elevator Mover control trigger, to summon the mover to specific frame.
FadeViewTrigger | Will fade the brightness of the screen.
FatnessTrigger | Changes size(fatness) of actor for specific time.
FearSpot | Area feared by pawns.
Jumper | A kicker but with less properties.
Kicker | Changes velocity and direction pawns.
MusicEvent | Plays/Turns-off specific song/music.
RoundRobin | Trigger one event from list each time it is triggered.
SpecialEvent | Multiple use event, sound, damage and message.
StochasticTrigger | Random trigger generator.
TranslatorEvent | Not used in UT.
Trigger | Default trigger.
TeamTrigger | Like a normal trigger but triggered by team players only.
TimedTrigger | Will trigger event a specific time intervals.
ZoneTrigger | Used to trigger zoneinfo actors.
TriggeredDeath | Instant death trigger.
TriggeredTexture | Will change the texture each time it is triggered.

This is the properties of a default trigger.
(Specific trigger properties are explained under each trigger).

Property | Specific
+Collision |
CollisionHeight | Height of the collision cylinder area.
CollisionRadius | The Radius of the collision cylinder area.
+Events |
Event | Ident name to be sent when trigger is triggered.
Tag | Used if the trigger should be triggered by other trigger.
+Object |
InitialState | Activation status of trigger.
+Trigger |
bInitialActive | If the trigger should be active or not.
bTriggerOnceOnly | Set if trigger can be triggered more than once or not.
ClassProximityType | Used if InitalState is "ClassProximity" to determine what class.
DamageThreshold | Used if InitailState is "Shoot" to determine amount of dmg needed.
Message | Displayed message each time trigger is triggered.
RepeatTriggerTime | Repeats the event for each time interval as longs as trigger is active.
ReTriggerDelay | Delay before the trigger can be triggered again.
TriggerType | This is how the trigger should be triggered.

Different Trigger Types:

TriggerType | Specific
PlayerProximity | Activated by all players, including real-life and bots.
PawnProximity | Activated by all creatures, players, bots.
ClassProximity | Activated by Class specific actors only.
AnyProximity | Activated by any type of actor.
Shoot | Activated by damage, "bDamageThreshold", from shot.

The trigger can also be controlled by other triggers.
This is the different "States" a trigger can have:

InitialState | Specific
None | Trigger will be inactive and useless.
OtherTriggerTurnsOff | Triggers "bInitalActive" will be false when triggered
OtherTriggerTurnsOn | Triggers "bInitalActive" will be true when triggered
OtherTriggerToggles | Triggers "bInitalActive" will change when triggered
NormalTrigger | Default and trigger is immune against other triggers.

Adding a trigger to the level:
The first thing to think of is, what are you going to trigger, when
and how.

When you know this you must determine the best solution to create this
event.
Maybe all you need is a mover as a trigger, or a zone portal?

Nevertheless, if you use a trigger you must set the correct properties.

By adjusting the collision cylinder size you affect the "detection" area of the trigger.
I a player/pawn or bullet hit the trigger collision area the trigger
will be triggered.

When triggered, depending on setting and trigger type, it will broadcast the event
to all objects.
All objects with the corresponding tag will be affected and act accordingly.
(Moving a mover, killing players and much more).

Some properties adjust the triggers behaviour, like "bOnlyTriggerOnce",
"RepeatTriggerTime" and "ReTriggerDelay".
If "bOnlyTriggerOnce" is true the trigger will 'die' when it have been triggered and
cannot be used again.
"RepeatTriggerTime" tell the trigger to repeat itself at a interval set by this property
as long as the triggering status are true (player in proximity).
(If zero this option is not used).
"ReTriggerDelay" sets a delay before the trigger can be triggered again.

If something is in the "Message" property it will be displayed each time the trigger
is triggered.

By setting "InitalState" to "ClassProximity" and then add an actor class to the
"ClassProximityType" property you can force a certain actor/fire type to be able
to activate the trigger.

 BioFear:
From what I know of this actor is that it is supposed to
make bots fear a given area (collision area of the actor).

However, I never got this to work properly.

It only have one propery and that is "bInitalActive" which
then can be triggered on/off.

From what I think, it could be used over traps and such places
where the status can be changed from deadly to harmless (traps?).

I will look into this some more and add it later.

 CodeTrigger:
This is a combination trigger.
Used to force players to active a given number of "CodeTriggers" in a specific
combination to allow for the "CodeMaster" (under info) to accept.

In the end it will trigger and event, which I think must be an elevator mover

I might add more info on this trigger at later a stage.

 Counter:
This trigger will only trigger an event when itself have been triggered
specific number of times.

bShowMessage - If messages should be displayed to the player or not.
CompleteMessage - Msg that will show when the counter reached a specific value.
CountMessage - Msg to show each time the trigger is triggered.
NumToCount - Num of times it needs to be triggered before it triggers the event.

This trigger can be used if you need players to perform multiple things before they
can proceed, like in AS-Mazon.

 Dispatcher:
The dispatcher work as a multiple trigger actor.
It can trigger up to 8 different events with specific delays.

Under "Dispatcher" you have OutEvents[] which is the
events to be triggered in sequence.
OutDelays[] is the delay before the corresponding event
is triggered (in seconds).

The dispatcher can only be triggered by other trigger.

Very usefull when you need a series of things to happen either at once
or after each other (delay).

 DistanceViewTrigger:
This actor is used to make bots pay attention to a triggering pawn.

It have no specific trigger properties and can only be triggered by a trigger.

When this actor is triggered, any pawn (bot) in its collision radius will
pay extra attention to who triggered it.

This is very useful to let bots, who are at defense points sniping, to
select strategic targets.
In the level CTF-Face this have been used.

 ElevatorTrigger:
This is a trigger to better control elevator movers.

The set of properties have been moved to "ElevatorTrigger".
Two new properties can be found here and that is;
GotoKeyframe which tells the elevator mover what keyframe to
arrive at.
MoveTime is just how long the mover should use to move to that
particular keyframe.

The ElevatorTrigger will only work with a ElevatorMover.

 FadeViewTrigger:
This actor will fade the brightness/color of the screen down.

There is a set of properties that handle this.
First there is "FadeSeconds" which is the amount of time
for the fade sequence (faster or slower fade).
The "TargetFlash" values should all be negative as it fades them down.

The last set of properties is "ZoneLight" that have "ViewFlash" and "ViewFog".
This is the same as with a normal ZoneInfo actor properties and give
the screen a default brightness.

FadeViewTrigger will fade the values from ViewFlash to the TargetFlash.
This means that the TargetFlash values must be lower than the ViewFlash values.

However, this do not seem to work 100% so I suspect that the the values
in ViewFlash and ViewFog should be the same as the current surrounding
(zoneinfo) values.

By fading the colors stepwise you could create a nice evening mood
fading the colors more and more.

It affect all players and must be triggered by another trigger.

 FatnessTrigger:
This is supposed to change the fatness of the object with the same
tag as the FatnessTag.

I never got this to work, I will see if I do and add the info later.

 FearSpot:
From what I know of this actor is that it is supposed to
make bots fear a given area (collision area of the actor).

As with BioFear I will check it out and add the info later.

 Jumper / Kicker:
(Jumper is the old Unreal version of UT's kicker).
It adds instant velocity in any direction to any pawn (player/bot) who
enter its collision radius.
bKillVelocity - Sets the actors velocity to zero before adding new.
bRandomize - Adds random velocity (don't know how much differance).
KickedClasses - Specific classes that can use the kicker (default Pawn).
KickVelocity[] - The velocity added to the pawn.

MusicEvent:
This actor, which must be triggered, can be used to change the current
state of the music.
Loading a new song, cutting off the current, set a new CD song with more.

All interesting properties can be found under "MusicEvent".
The first, bAffectAllPlayers, determine if all players will be affected
by the music change.
bOnceOnly - if the music change should only happen once.
bSilence - will turn off all music selections, resulting in no music at all.
CdTrack - is what track to play from the CD, value 255 for none.
Song - is a .umx file from the UT music folder.
SongSection - can be used to start the music from another section rather
than the beginning.
Transition - is simply the flow from the current music state to the new one.

You can use this to change song in different areas to give a much more detailed
mood.
The load time before you start can be a bit longer but should not be a problem
in-game.

RoundRobin:
This actor will trigger an event each time it is triggered, in sequence from
a list.
OutEvent[] is the list of events which you want this actor to trigger, in
sequence, up to 16 events.
bLoop, either true or false will tell the actor to start the list
over again, from OutEvent 0 when the last OutEvent have been triggered.

This actor must be triggered by other trigger.

Usefull if you want different things to happen each time a player trigger
this actor.
It will only trigger one event for each time it is triggered, and then go to
the next OutEvent.

SpecialEvent:
This actor is used to show messages, play sound effects and hurt players.

Some important properties and states combined say what it should do.

bBroadCast - Show message to triggering player only (false), or all (true).
bPlayerViewRot - Don't know what do.
Damage - Amount of damage inflicted if initial state is "DamageInstigator".
DamageString - Message to show when player dies from this event.
DamageType - Type of 'harm', like "Burned", "Corroded" and so on.
Message - Message to display on screen when triggered.
Sound - Sound effect to play when triggered.

The different initial states tell how the Special Event should act.
None - Useless
PlayerPath - Single Player mode only, useless for UT.
PlayAmbientSound - Will play the sound under "AmbienSound" for the player.
PlayerPlaySound - Will play soundeffect for all players in the game.
PlaySoundEffect - Will play soundeffect from the event location only.
KillInstigator - Kill player instantly.
DamageInstigator - Hurt player specific amount of damage.
DisplayMessage - Simply shows the "Message" on screen.

If you use PlayAmbientSoundEffect, the sound effect used is under "AmbientSound"
and not "Sound" that is used for "PlayerSoundEffect" and "PlaySoundEffect".

However, you should not add a sound effect to the "AmbientSoundProperty" and have
the "PlayAmbientSound" state as it will cause the sound effect to loop twice.
First the sound effect plays from start and then another one is started
when the event is triggered.
Use "TriggeredAmbientSound" instead (see the sound tutorial for more info).

Different Damage Types:
Fell, Decapitated, Corroded, Burned, Drowned, Frozen, SpecialDamage.

 StochasticTrigger:
This is a random trigger generator.

The initial state of this actor is either "AlwaysActive" or "TriggerActive"
which means that if you want the random generator to work from start, or if
you need to trigger it to start it.

The properties you have, under "StochasticTrigger" regulate chance
of trigger, what trigger and delay between random test.
Events[] - When random is success, it will trigger a random Event.
maxReCheckTime - Max delay before actor tries a random check again.
minReCheckTime - Minimum delay before actor tries a random check again.
triggerProbability - The chance of a random generator, between 0 and 1.

This can be used when you want to produce random events in the game, like lightning.
The random generator takes a value between 0 and 1, meaning that 0.5 will
be 50% chance.
If you set 1 it will be exactly like a timed trigger.

 Trigger:
This is a regular trigger.
When the correct "TriggerType" conditions are met an event will be sent
and affect all objects that have the same tag as the trigger event.

 TeamTrigger:
This work just like a regular trigger but have additional "TeamTrigger"
properties.
This is what team ("bTeam") that should NOT be able to trigger it.

There is also "bTimed" which I am not sure what really do.
If I figure it out I will add the info.

 TimedTrigger:
The Timed Trigger is supposed wait specific time and then trigger an event.
Additional "TimedTrigger" properties allow you to adjust this.
Use "bRepeating" if you want the trigger to repeat itself or not.
"DelaySeconds" is the delay before the trigger triggers the first time and
each time if "bRepeating" is true.

This trigger is always active and cannot be triggered by player or other trigger.

 ZoneTrigger:
This trigger act exactly like a regular trigger but with one difference.
When triggered it will activate a zones "bPainZone" (set true).

 TriggeredDeath:
Instant death for the player who trigger this actor.

With a lot of properties which adjust the screen flashing, if items should
be destroyed, sound effects and time it is triggered to actual death.

This is useful if players travel in "deadly" areas they should not be in.

Must be triggered by other trigger.

 TriggeredTexture:
You are supposed to be able to change the texture with this trigger.

Never got it to work correct. Might look into it and add the info later.

 Other ways of trigger:
There is more than one way to create an event (triggering).
Actually this happens all the time, but as a player you do not
notice it.

As a rule an event will be triggered when the object/actor have served
its purpose.

Mover completes its move cycle, player grabs the flag, activates the control point,
entering a zone and so on.

This should be taken advantage of as much as possible.

The most common is probably a mover.
When a mover completes moving from keyfram 0 to the last it will trigger
an event.
This can be used to chain connect multiple movers/items.

 Need to be triggered:
Lots of actors under the trigger class need to be triggered by another trigger.
This means that you need to place not only the actual actor but also something
to trigger it with.
Some of the actors that need to be triggered is,
MusicEvent, DistanceViewTrigger, Dispatcher, RoundRobin and so on.


TRIGGER TUTORIAL

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

Hmmmmm........ what's this tutorial doing here :). This tutorial will show you what a trigger is and how to make use of it in all kinds of situations - I will be covering everything that should help both BEGINNERS. I will try to make this tutorial as comprehensive as possible. At the beginning ....................... then :0).

BASIC TRIGGERS

A trigger is an actor that allows you to setoff other events when it is activated. For example say you could have a trigger that when touched causes an earth quake. The most common uses of a trigger is to have it open a door or kill the player who touches it. Lets take a simple example and see how to make music play in a silent level or make a music transition.

First make a room it doesn't matter what size and the place a trigger in the center of the room. You'll find it under actor > triggers > trigger : -

NOTE :- Do not expand trigger just select it the others will be of use later.

Ok now under triggers you will find another actor called music event place this in the level (it looks like an eagle head). It does not matter where exactly you place a music event in the level - but the trigger matters a lot. The following information is very important so burn it in your mind.

To make the trigger activate the music event you need to properly tag them up by using both the items found under their respective properties in EVENTS. First open the triggers properties and set EVENTS>EVENT to "musicchange" without the quotes. Now go to the properties of the music event and set the EVENTS>TAG to "musicchange". THE EVENT OF THE ACTIVATOR MUST MATCH THE TAG OF THE THING BEING ACTIVATED.

This is how you must always set up the events and tag for anything you want activated. Like these two dialogs :-
Besides this you must immediately go to the top or any of the side views and verify that the event and tag (in this case the trigger and the music event) are linked by a red line. See below:-

Now place a player start in a corner of the room and we'll see how to set the area that the trigger affects. This works through radius system. To see the radius of the trigger, right click on anywhere on the top part of any of the view 9near the joystick button) and in the menu that appears choose view> actors > radii view. Now set this in all four views and when you see the trigger in the 3d view you'll see a red cylinder denoting the area that the trigger affects. You'll see that it is too small. Now go to the triggers properties, and under collision you'll find the collision radius and collision height. Play around with this until you get the radius and height that you need. My room is 512x768x768 so I used the following:-

The basic part is not over yet and we have a long way to go {:(. Time to configure the music event. Just go to it properties and under music event (duh........... moose woulda been proud of me ;), set this :-

Make sure that you first load up your fav music track from the music browser before selecting it and hitting the use button in the song subsection in MusicEvent.

Fire your level and when you walk into the center of the room you will find that the music changes from silence or what ever was playing before to the new song. Earth to Mars : Basic Triggering triggered Sir. :).

TRIGGER PROPERTIES

Ok previously we only changed the collision height and radius of the trigger. Usually (most of the time actually) you need not change anything else. Most of the items are self explanatory but sometimes when looking for a cool effect to do you keep wondering where to find it till some one either points it out or you spend hours trying to locate it. Ok here's the other properties that you can change for a trigger (assuming you have properly set up the event and tag as described above) :-

  • bInitiallyActive - Whether the player on touching this trigger itself can activate the event or whether it must be activated by another event or another trigger.

  • bTriggerOnceOnly - Great for one time puzzles and events that you want to happen only once. Say like a secret door that you want to be triggered to open only once and then stay in that state till the end of the game.

  • ClassProxmityType - Can only be activated by this type of pawn. This particular bot is found under pawn > bot > humanbotplus > tmalebotplus > tbossbot.

  • DamageThreshold - The amount of damage the trigger can take before it is put in a triggered state. See also Trigger Type.

  • Message - The message to display in the Heads-Up-Display (HUD). Note to display the message across the screen you need to set off a special event. The Special Event tutorial can be read here.

  • TriggerType -

    • TT_PlayerProxmity - Normal Trigger.

    • TT_Shoot - You need to shoot (duH ................ its me Einstein :() it to activate the trigger.

    • TT_PawnProxmity - Can be activated by any pawn found under the pawn menu but not the player.

    • TT_ClassProxmity - Can only be activated by the specific type of class specified in the ClassProxmityType field. This was used by the unreal1 developers to make those friendly Nali sequences. That's where you can never seem to be able to open a door but when the Nali steps in the radius of the trigger the door or whatever is activated. And don't forget to set the Class proximity type to Class'UnrealShare.Nali' or whatever.

  • ReTriggerdelay - After how much time the trigger can be activated again


deCyber Build Section

Triggers

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Accompanied files : Triggers.UNR

Contents

1) Basic_Principles
2) Ordinary_Trigger
3) Biofear and Fearspot
4) Code Trigger and Elevator Trigger
5) Counter
6) Dispatcher
7) Distance View Trigger
8) Fade View Trigger
9) Fatness Trigger
10) Jumper and Kicker
11) Music Event
12) Round Robin
13) Special Event
14) Stochastic_Trigger
15) Translator Event
16) Team Trigger
17) Timed Trigger
18) Zone Trigger
19) Triggered Death
20) Triggered Texture
21) Movers
20) Pawns

Introduction
During a level, several things should happen to a player to make the game interesting and not just a scenic stroll around a new world. Doors, sudden alien ambushes, moving spacecraft, puzzles and all manner of different scripted events need to use some form of trigger.

1) Basic Principles

In brief, a trigger is an "actor" (one of the classes from the "ActorClassBrowser"), or a brush which primarily uses two things: "Events" and "Tags". The event is what you want to happen and the "Tag" is what you want it to happen to. For example, in a level, you might push a button that opens a door.The button would have an "event" called "opendoor", and the door itself would have a "Tag" called "opendoor". So when ever the button is pushed it sees the event is called "opendoor" and looks for any tag that matches that and executes that item's command. It is also possible to have several items that all have the same tag.When that tag name is called on, all of them will respond. I don’t know what all of the triggers do and how they work, but I can share what I do know.

That is the basic principle of the trigger.

2) Trigger (ordinary)

This is the first one you need to know about and is simple to grasp. All the other trigger functions use these properties, but with other functions added. (Make sure you select the Trigger which has the 3 other subclasses and not the main one).

To get an ordinary trigger to do something click on the trigger and bring up the properties box (F4). Under the property called "Events" you find two fields, "Event" and "Tag". Under the field called "Event" type in the name of the Tag for the item(s) you want to effect. (If in doubt see the example map).

By default, this trigger will operate when a player runs into it, but altering the properties can change this. Go to "Objects" and
then click on "Initial State" and you will see the follwing options:

Other Trigger Turns Off:
This trigger remains active until a different trigger acts on its "tag" and switches it off.

Other Trigger Turns On:
As above but another trigger causes this one to become active.

Other Trigger Toggles:
The trigger will be switched on and off like a light switch each time another trigger acts on it.

The above options tell Unreal how the trigger is operated, but you can also tell it who or what can act on it. Click on "Trigger Type" in the options property and you will see another list of options appear as follows:

Player Proximity:
This is the default setting and the trigger can only be activated by the player.

Pawn Proximity:
Any pawn, such as the player, A Skaarj, or even a rabbit can set this trigger off.

Class Proximity:
This broadens it even further. Any class can activate it.

Any Proximity:
Speaks for itself. If anything comes near it (apart from another brush I think) it will be triggered.

Shoot:
The trigger will only activate when a projectile hits it.

3) Bio Fear and Fear Spot

I'm not sure what the difference is between these two triggers but they appear to do the same thing! These triggers creates an area which other pawns are scared of and so will avoid.

4) Code trigger and Elevator Trigger

The code trigger has something to do with Elevator triggers apparently, though I’m not sure what!
The elevator trigger is a very useful trigger to be used with an "Elevator Mover". In this trigger you
can tell the elevator mover to move directly to any one of its keyframes.

see also the tutorial on MOVERS

5) Counter

This is a very useful trigger. Each time it is triggered, it will increment its count by one until it reaches the number specified by you in the "NumToCount" field. When it has finished counting it will then trigger of another event (in its "Event" field). This is very useful for puzzles.

For Example:
You can have 5 triggers set up so that their "Event" property is linked to the "Tag" property of your counter. These triggers can then be set off in any order, but the counter will not trigger off anything else until the other 5 triggers have been activated.
If you want the player to know what’s happening set the "bShowMessage" field to "true" and then use the "CompleteMessage" and "CountMessage" to say whatever you want. (%I is the current number that the counter has reached).

6) Dispatcher

In my opinion this is the most useful form of trigger. There will be times when you need to script a particular event, and you will need several things to happen in sequence, or all at the same time. The example on the left will give you an example of how this works. In the "OutEvents" properties, you can type in your various events, and the dispatcher will run through each of these in order. In the "OutDelays" you can tell the dispatcher at want point in time to introduce each event. In this example an explosion occurs followed by an earthquake and a rumbling noise 1 second later. 4 seconds after that debris is triggered to fall. 2 seconds later all the lights go out and 6 seconds after that screams can be heard. Take a look at the sample map if you need to experiment with it.

7) Distance View Trigger

When this is triggered, it will alert all pawns within its specified radius. You can change the radius of your trigger by adjusting its "collision" properties. By default this will be 40 but you can increase this if you like. If you want to see how far the scope of the radius extends in your top view 2D grid all you need to do is right click in a blank part of the window's menu (perhaps next to the little icon that looks like a joystick) and select "actors" and the choose "radii view". You should see a red circle around the trigger showing how far its reach extends.

8) Fade View Trigger

This is probably used most for assault maps when the game is complete but could be very useful for SP levels too. When triggered it will fade the screen out slowly to blackness. You can specify the amount of time it takes to do this by adjusting the figure in its "FadeSeconds" field under the "FadeViewTrigger" section of the trigger's properties.

9) Fatness Trigger
I suspect this has something to do with altering the "fatness" of a particular actor in its display property.
(e.g. The Nali fatness reduces in size when it teleports away in single player). However, I have never been able to get this to
work!

10) Jumper and Kicker
Again, I'm not certain what the difference is between these two triggers but they appear to have the same function. When a pawn hits this trigger, it will jump (duh?). (Useful for getting monsters to jump off ledges).

11) Music Event See tutorial on MUSIC

12) Round Robin

This trigger has a long list of "OutEvents" each of which can contain a different Event. Everytime the RoundRobin is triggered it will activate the next Event in its sequence. If the "bLoop" field is set to "true", it will do Event 0 after the last specified Event and continue to cycle in this way. If "bLoop" is set to "false" (by default), it will finish at the last specified EventAt this point if there is a Tag specified in its normal Event field it will activate that one.

13) Special event:

This is a very useful trigger and can be used for a variety of different effects. Other triggers operate this trigger rather than the player walking in to it, so you will need to give it a "Tag" name (e.g. "effect"). Set up an ordinary trigger as listed in section 2 and call the "event" of that trigger "effect".

To use it, place this trigger in your world and bring up its properties. Click on "Object" and then on "Initial state".
You will see a variety of options which you can use. Here's what they do:

PlayerPath
Player path is used for "interpolation" which is used for flybys (like the Unreal opening sequence) or cut scenes. This will be covered in a future tutorial.

PlayAmbientSoundEffect
For triggered sounds that you want to stay permanently on (e.g. turning on a piece of machinery) choose this option.
All you then need to do is choose your ambient sound and place it in the "Sound" field uner the "SpecialEvent" section (not the usual sound section)

PlayersPlaySoundEffect
For one-shot triggered sounds that sound as if they come from the player (e.g. speech) you need to choose this option. The sound will always eminate from the player rather than from the trigger. All you need to do then is choose your one-shot sound and place it in the "Sound" field uner the "SpecialEvent" section (not the usual sound section)

PlaySoundEffect
For one-shot triggered sounds (e.g. a distant explosion) you need to choose this option. All you need to do then is choose your one-shot sound and place it in the "Sound" field uner the "SpecialEvent" section (not the usual sound section)

KillInstigator
Choosing this option will cause whoever triggers the special event to die instantly. This is good for laser beam forcefields and similar things.

DamageInstigator
Similar to the KillInstigator option but just wounds whoever triggers it by the amount specified in the damge field.

DisplayMessage
Using this will display a message in white text in the corner of your screen. Just write your message in the message field.
Changing "bBroadcast" to true will cause the message to bleep and display it in blue text in the centre of the screen to all players.

NOTE: If you're not familiar with how to use sounds then See the tutorial on SOUNDS.

14) Stochastic Trigger:

This will enable you to perform random events at random times. Just add the events that you want in the event fields. It works
in exactly the same way as the "DynamicAmbientSound" actor which you can read about in the SOUNDS tutorial.

15) Translator event

This is the particular trigger you need to give the player a message during a single player game. These are triggered as soon as a player walks over them. Make sure they’ve been given a translator device at the beginning of your level. Once you’ve added this trigger to your world, bring up its properties and click on "translator event" and you will see some more options appear where you can type in a message.

16) Team Trigger

This is used for team games. When triggered it will trigger all pawns in the game apart from the pawns in the team number specified by the trigger.

17) Timed Trigger

I used to use a Dispoatcher for this function as events can be timed using that trigger. The "Timed trigger" does simplify matters though and has one other useful function. When triggered, it will wait for the amount of seconds specified in the "DelaySeconds" field before it triggers something else (specified in its own event field). The extra useful function that a Dispatcher can't do is loop itself. If bRepeating is set to true, the timed event will be triggered after the same amount of time again and again.

18) Zone Trigger

Used to trigger an event when a zone is entered. See the tutorial on ZONES to find out what they are if you don't know.

19) Triggered Death
When a pawn (including your player) hits this trigger, they die immediately.
Useful for electrical force fields, rocket thrusters and that sort of thing.

20) Triggered Texture

Useful for those moving banners that you see in Death match levels. I'll be submitting a specific tutorial for this in the future.

21) Using a mover as a trigger.

In the same way any trigger can activate something else with its "Event" property, a mover can do exactly the same thing. Just put the "tag" name of the item or trigger you want to activate in the "Event" property of your mover, and when your mover finishes its moves it will activate the other item.

See the tutorial on MOVERS for details.

22) Using a pawn as a trigger.

This will be useful mostly for SP levels. There are several ways a pawn can activate a trigger. See the tutorial on Creatures over at Unreal Technology for more details, but in short, here they are.

a) Use alarm points to guide your monster to the trigger you want to be activated and set the triggers "Triigertype" attribute to TT_PawnProximity. Or you can also set the event field of any of the alarm points your pawn reaches.

b) The monster’s "Event" field can be used as a trigger when it dies.

c) The "PlayerFirstHateEvent" can be used as a trigger when a monster first becomes aware of a player.

EZkeel
(Simon West-Bulford)


The Trigger Actor

By : Joshua 'Techno JF' Fields

Reviewer for : http://www.unrealsp.org

Compiled Location of Actor: Engine.Trigger
Location in Object Hierarchy: Actor/Triggers/Trigger
Function: When triggered by an actor entering its defined proximity (see TriggerType property), it passes its event name to trigger any actors with this tag.

Relevant Configurable Properties:

Variable | Location | Effect
CollisionHeight | Collision | For the Trigger to pass its event, a valid actor must come within this vertical distance of it (in Unreal Units).
Collision Radius | Collision | For the Trigger to pass its event, it must be encroached within this horizontal radius.
InitialState Object Specifies when the Trigger will pass events to relevant actors.
  • None: The trigger is permanently inactive. (I have not found a use for this.)
  • NormalTrigger: The Trigger is permanently active. (This is the Trigger's default state.)
  • OtherTriggerTurnsOff: When the Trigger’s Tag name is called, the Trigger will be permanently deactivated.
  • OtherTriggerTurnsOn: When the Trigger’s Tag name is called, the Trigger will be permanently activated.
  • OtherTriggerToggles: When the Trigger's Tag name is called, the Trigger will be turned off if it was currently on, and vice versa.
bInitiallyActive | Trigger | This determines whether the Trigger is active or inactive just as the level is beginning.
bTriggerOnceOnly | Trigger | If set to True, then the Trigger will be destroyed after it is triggered once.
ClassProximityType | Trigger | See the TT_ClassProximity choice under the TriggerType variable description for information.
DamageThreshold | Trigger | See the TT_Shoot choice under the TriggerType variable description for information.
Message | Trigger | When the Trigger successfully passes its event, it will also print this message on the screens of any players.
RepeatTriggerTime | Trigger | This property is inactive if set to 0. If the actor setting off the Trigger is remaining within the Trigger’s proximity, then the Trigger will pass its event over and over again at this interval until the actor leaves the Trigger’s proximity.
ReTriggerDelay | Trigger | After each time it passes its event, the Trigger is prevented from doing so again until this length of time has elapsed.
TriggerType Trigger Specifies what will cause the Trigger to pass events to relevant actors.
  • TT_PlayerProximity: Only a PlayerPawn can set off this Trigger.
  • TT_PawnProximity: Any Pawn can set off this Trigger.
  • TT_ClassProximity: Only an actor of the type defined in the ClassProximityType property can set off this Trigger.
  • TT_AnyProximity: An actor of any type can set off this Trigger.
  • TT_Shoot: Only when the Trigger is shot can it be set off. (This could have been called TT_ProjectileProximity.) The Trigger must sustain at least as much damage as is specified in the DamageThreshold property.

Tutorial:
This is such a fundamental actor that I really have no idea how to create a tutorial specifically for it. However, I have included numerous tutorials that use a Trigger in conjunction with another actor. I advise looking up one of these tutorials if you want to see the Trigger in action. The tutorials on Movers, Dispatchers, and MusicEvents are probably the best ones to look at.


The Dispatcher

By : Joshua 'Techno JF' Fields

Reviewer for : http://www.unrealsp.org

Compiled Location of Actor: Engine.Dispatcher
Location in Object Hierarchy: Object/Actor/Triggers/Dispatcher
Function: when it is triggered by another actor, it goes through a list of tags and time delay values, and triggers them in order with the given delays.

Configurable Properties
Variable | Effect
OutDelays[8] | The array where the time delays between consecutive events is recorded. Note: these times are not the lengths of time from when the Dispatcher is initially triggered. They are the times delays between one event and the next. The first blank indicates the time delay from the initial triggering.
OutEvents[8] | The list of tags to go through and trigger.

Tutorial:
Since this actor is meant for handling complicated scripted events, I have something interesting in mind. Let's try first creating a simple room with the essentials. Now, put a Trigger, a Dispatcher, an Earthquake keypoint, a MusicEvent, and a SpecialEvent. You need to make sure that the Trigger is not touching the PlayerStart, but the location of each of the other actors in this room is irrelevant.

The default setting for the Earthquake will suffice. Put some kind of distinctive sound in for the SpecialEvent, and set its InitialState in the Object menu to PlayersPlaySoundEffect. Choose a piece of music put into the MusicEvent actor as a Song. Afterwards, we link the actors together. Make the Trigger's event match the Dispatcher's tag. Then fill in events in the OutEvents array that match those of the SpecialEvent, Earthquake, and MusicEvent, in that order (into blanks 0, 1, and 2). Finally, open the OutDelays array and fill in values of 0 seconds, 3 seconds, and 6 seconds.

When you test this map, go over to the Trigger. When you touch it, three things will happen.

  1. You will hear the sound you chose for the SpecialEvent instantly. It will appear as though you are the source of the sound.
  2. You will experience the Earthquake 3 seconds after the sound started playing. According to its settings, the quake will be rather strong, and it will last for 5 seconds.
  3. 6 seconds after the beginning of the Earthquake, you will hear the music start playing.

This is a very versatile actor. It is capable of doing many things. One of the interesting tricks it is good for is correcting problems with music files that play some sections at bad tempos. You can find this technique explained along with the MusicEvent actor.

Another use for this actor is for the purpose of acting as a time delay between the actions of two actors. This just requires the use of one pair of variables in a Dispatcher to work. Instead of the first actor triggering the second, it triggers the Dispatcher. This Dispatcher then waits for the length of time specified in OutDelays[0] before it triggers the second actor.


The RoundRobin

By : Joshua 'Techno JF' Fields

Reviewer for : http://www.unrealsp.org

Compiled location of actor: Engine.RoundRobin.
Location in Object Hierarchy: Object/Actor/Triggers/RoundRobin.
Function: when triggered, it immediately triggers one of a number of events in a list, advancing to the next tag in the list each time it's triggered.

Configurable Properties
Variable | Effect
OutEvents[16] | The list of events that the RoundRobin cycles through when it's triggered.
bLoop | If set to True, then the RoundRobin will start over at OutEvents[0] when it reaches a blank event or the end of the array. If set to false, then the RoundRobin will become dormant at this time instead.

Tutorial:
This actor is not used very often, so trying to devise a scenario to show it off required quite a bit of brainstorming. What I came up with isn't fancy, but it will suffice.

Start by creating a room with all the necessary features, such as light and a PlayerStart. Now you need several SpecialEvent actors. I think that four of these will suffice. Set all of them to the PlaySoundEffect state in their Object properties, and put one of them in each corner of the room. For each of these SpecialEvent actors, put a different sound in for its Sound property. A good place to choose sounds is from the Activates.uax file or the AmbAncient.uax file. (Just remember to only use OneShot sounds if you get them from the AmbAncient file.) Finally, give each of them a unique tag name.

Now place a Trigger somewhere in the room where you can find it, and yet where you are also capable of leaving it. Also, place a RoundRobin in your room somewhere. Set your trigger up so that it triggers the RoundRobin, and set your RoundRobin up so that its first four OutEvents blanks contain the tags of those four SpecialEvents. For this tutorial, you don't need to put them in any specific order, but you do need to remember what order you put them in. Also, make sure that bLoop in the RoundRobin's properties is set to True.

Once you have finished putting all of this in your level and have rebuilt everything, it's time to test this level. When you touch the Trigger, you will hear the first SpecialEvent play its sound. If you leave the Trigger and then touch it again, you will hear the second SpecialEvent play its sound. Doing this two more times will cause you to hear the third and fourth SpecialEvents.

Now, remember that we made sure bLoop was True in the RoundRobin's properties. So, if we touch the Trigger a fifth time, we'll hear the first SpecialEvent again, because the RoundRobin was told to start over when it came to the end of the list.

A RoundRobin can also be made to simulate a Counter. The difference is that a Counter cannot be made to broadcast its event again after it has done so once. So, let's say that we need an event to happen only every fifth time it's triggered. Well, a Counter can't do this, but a RoundRobin with bLoop=True can.

Using the number 5 as an example, you can set up the OutEvents array to make this work. Put the event in the fifth blank in the array, which is OutEvents[4]. Next, you need to fill in some dummy event for all the blanks before it. I suggest either giving some PathNode in your level an interesting tag, or putting a MakeNaliFriendly actor in your level for the RoundRobin to trigger. (If you have any Nali in your level, then I would go with the PathNode tag.) Finally, give your RoundRobin the tag that you want it to be triggered with.

The result is that you have a construction that will only cause the event to be triggered every fifth time.

There is a way to expand this method to have extra restrictions, but it requires much more work. Let's say that you need a Mover to move whenever three items in the level are shot. While this is guaranteed to work properly when set up right, it is not easy to set up at all.

First, let's create all of the actors we need before we actually fill in any of their properties. (I'll use the number 3 as an example, but I'll explain this method as though any number was being used.) You need a Trigger in the level for each of the three items, you need two RoundRobins, and you need one Dispatcher for each Trigger you have, plus an extra Dispatcher. Obviously, you also want the Mover or whatever you're going to trigger. Finally, you'll need either a PathNode or a MakeNaliFriendly actor to act as a dummy actor to trigger.

Next, let's set some of our variables. Set all of the Triggers so that they are of TriggerType=TT_Shoot. Then put them all into InitialState=OtherTriggerToggles. Make sure that bInitiallyActive=True in all of the Triggers. In both RoundRobins, make sure that bLoop=True. Finally, set up your Mover so that it works the way you want it to.

Now we get to the point of assigning Events and Tags. To make more sense out of this, let's assign matching Events and Tags at the same time. Okay, bear with me for this, and read and do each step before going on to the next.

  1. Give each Trigger a unique Event, and then make each of these a Tag for a Dispatcher. You'll have one Dispatcher left without a Tag when you're done.
  2. Count your Triggers and then open the properties for one of your RoundRobins (let's call it RoundRobin #1). In this case we have three Triggers, so we put a unique event into the third blank of RoundRobin #1's array, OutEvents[2]. Then make this the Tag for RoundRobin #2.
  3. Give that PathNode or MakeNaliFriendly actor a unique Tag, and then fill this into the OutEvents blanks that you skipped over RoundRobin #1. We have three Triggers in this case, so you should have skipped only two blanks.
  4. Give the Mover a unique Tag. Then go into RoundRobin #2 and put this Tag in the first OutEvents blank.
  5. Give each Trigger a unique Tag. Then open each matching Dispatcher and put that Trigger's Tag in the first OutEvents blank.
  6. Give RoundRobin #1 a unique Tag. Then go into each Dispatcher and put this Tag into each of their OutEvents arrays.
  7. Look at the Tag for RoundRobin #2, and make this the Event of the Mover.
  8. Do you notice that we have a Dispatcher that we haven't even touched yet? Give this Dispatcher a unique Tag, and then put this in the next OutEvents blank in RoundRobin #2.
  9. Finally, look at all of the tags for the Triggers, and fill them into the OutEvents blanks for that last Dispatcher.
Whew! That was a lot of work! Now, if you're interested, I'll explain how it does what it does.
  1. When one of the Triggers is shot, it tells its Dispatcher to do two things.
    1. Turn off that trigger that we just shot, and
    2. Trigger RoundRobin #1.
    RoundRobin #1 doesn't do anything that time because it just triggered the dummy actor.
  2. When the last Trigger is shot, it tells its Dispatcher to do the same things, but there is one difference. RoundRobin #1 finally gets to the blank where it triggers RoundRobin #2. RoundRobin #2 triggers the mover, and the mover does its job.
  3. When the mover has finished doing its job, it triggers RoundRobin #2 the second time. This time, RoundRobin #2 triggers that last Dispatcher, which turns all of the Triggers back on. This means that everything is back in the original condition that it started in, and it can all be done over again.


Advanced Triggers

by: Cold Front
cjames@henninger.com

While this process is not difficult, it is very complex. It contains many steps that you will have to follow in order to get your triggers working. I suggest that you download the map provided and follow along. If you can not have a browser open while in unrealed please print out this document. The first step should be to view the map in Unreal. This will allow you to have a sense of what you will be working with. When you start the map up, walk forward a little bit and you should notice a few things, these being:

  • An earthquake

  • Explosions

  • A Screaming sound, and an earthquake sound

  • Music

  • On/Off lighting sequences

All of these things were done easily using Triggers.

Behind the Scenes:

In the map you should have downloaded I duplicated the geometry for you so you can try this yourself, with my setup as a reference. So before you do anything, CNTRL-drag the PlayerStart position (looks like a joystick) over to the empty hallway. The very first thing that you must do is lay down a main Trigger. To do this go to Classes -> Actor -> *Triggers ( If you don"t know what Im talking about, come back to this tutorial when you are more experienced with UnrealED). Expand the *Triggers heirarchy and you should see "*Trigger" (no "s") with a white dash next to it. Click *Trigger once so that it is selected (don"t open the heirarchy..do NOT add a ZoneTrigger, just *Tigger). Now, somewhere in the empty hallway Right-Click and choose, "Add Trigger here" from the pop-up menu. You should see a black box icon. This is your trigger, and is what will set off a sequence of events if the player is within a certain radius of it. With open up your Trigger"s properties. Expand the "Collision" menu. Now notice where it says CollisionHeight and CollisionRadius. These are important factors as they decide how close to your Trigger the player has to get before it is set off. For the sake of this tutorial lets change the CollisionRadius to 240.00 to ensure we set it off in the hallway.

    Advanced Users Note: The "Trigger" menu in properties usually doesnt need to be touched if you want just your player to set off the trigger, but if you want other items to set it off then change the TriggerType from TT_PlayerProximity to any of the other values such as TT_PawnProximity (Nalis, Skaarjs etc can set it off), or TT_Shoot (bullets, or any other projectiles can set it off) or TT_AnyProximity would allow just about anything to set the trigger off.

Ok, with our CollisionRadius all set. Expand the "+Events" menu in the Properties window. You should see Event and Tag. These are vitally important. Im not going to give you the whys or whatfors, im going to tell you what value you spit in there and let you figure out how the correlate :) Ok for Event: put in "MyTagName" (sans apostrophes of course). And for Tag: put in "Trigger" (this value is really insignificant in this tutorial). Ok now, close that Properties window and save.

The next step is to add your first event (the order that you add events really doesn"t matter). This being the sounds that will be triggered. Under Classes->*Triggers highlight "*SpecialEvent". Now add one of these to the hallway. This icon should look like your Trigger icon,but with an exclamation mark on it. Now open up the Properties of your SpecialEvent. Under the Events menu, set Event: to "None" and Tag: to "MyTagName". I said I would go through all this but, basically the Event parameter is what is sent out when the Triggere is activated, and any items like earthquakes, or MusicEvents that have a Tag that is the same as the Event parameter, are activated! So because we are giving this SpecialEvent"s Tag the same name as the Triggers event when ever the Trigger is activated it will activate the SpecialEvent. Get it? Didn"t think so... :)

Anyway...as soon as you entered "MyTagName" as the Tag name you should notice that a red line now connects your Trigger and SpecialEvent. Now, still in the Properties window, under "Object", change the InitialState parameter to PlaySoundEffect. Then, under SpecialEvent in the Properties window, change bBroadcast and bPlayerViewRot to False if they are not already. Then where it says Sound, choose the sound you want to play when the trigger is activated ( you should know how to do this), and click Use. I choose one of the screams from the Rikers set.

Next, click on the SpecialEvent icon (the one with the exclamation point on it) and duplicate it once (another red line should connect the Trigger and this new duplicate). Keepal of the settings the same, except go back into Properties>SpecialEvent>Sound and choose one of the earthquake sounds from the AmbOutside set.

Save your map.

What you have now will work. As the player gets activates the trigger, you will hear a scream, and an earthquake sound. Lets not play it in unreal just yet, besides its all dark in your hallway right now anyway :) So lets spice things up some more and add Music! Under Classes->Triggers highlight "*MusicEvent", and place this somewhere in the hallway. The icon should look like a serpent"s head. Open up the Properties of the MusicEvent, and make the following changes: Under Events, Event should be "Trigger" and Tag should be "MyTagName" (are you beginning to see how the whole tag thing works now?). Under MusicEvent, make sure that bAffectAllPlayers is True and that bSilence is False. If you want your song to keep repeating over and over mane bOnceOnly False. Still under MusicEvent, change Transition to MTRAN_Instant. The Transition parameter sets how the music comes in. A setting of Instant will make the music instantly come on, but you could also choose a slow fade or whatever floats your boat. Ok you should notice that another red line is connected from your Trigger to your MusicEvent icon.

Now lets add an Earthquake! You can find Earthquake under Classes->*Keypoint->*Earthquake. Add one of these to your hallway. The icon should look like a black box with a key on it. Open up the Properties for the earthquake event, and make the following changes: Under Events, Event should be "None" and Tag should be "MyTagName". Notice that I changed from using "Trigger" as the event to "None". This is to show that the Event is not significant in the actions unless you want to have a chain. For instance say you wanted to have the Trigger activate a MusicEvent, and then you wanted the MusicEvent to activate an earthquake, you would just give. Trigger"s Tag as IceTea,its Event as "Coke". Then the MusicEvent"s parameters would be, Tag: "Coke", Event: "Pepsi", and the earthquake"s settings would be Tag: Pepsi, Event: None. None becuase its the end of the chain and therefore useless. Not vital if you don"t understand this yet. Ok moving on...

Under Earthquake"s Properties, expand the Earthquake menu. Let me explain each parameter and you can fill in what you please:

  • bThrowPlayer: If this is True then the player will be tossed all around the map during the course of the earthquake. if it is False, then the player"s feet will remain planted while the world shakes so just the player"s view gets a little shaky.

  • duration: Numerical value in seconds of how long the shaking will last.

  • magnitude: the ferocity of the earthquake, or in layman"s terms, "how shaky that bitch will get" anything more than 3500 is pretty rediculous.

  • radius: not exactly sure but most likely how large of a region around the earthquake event icon is affected.

For the sake of this tutorial set the values to: True, 3.0, 1500.0, 300.0 respectively. (check the values on my side of the map if you are not sure). There should be another red-line connecting the Earthquake event and the Trigger.

Now lets add some cool explosions. Under Classes->*Effects you should find "*ExplosionChain*" Place one of these in the hallway, a little farther away from the other events so the player doesn"t get blown up :) Change the following in its Properties:

  • Events->Event: "None" Tag: "MyTagName"

  • Effects->bOnlyTriggerable: True, and None for both sound effects

  • ExplosionChain: Damage 100.0 (this is how much health the player eats when this explosion goes off hear her). Delay time 0.3, Momentum Transfer 100000.0, size 2.0

Great you should now see a red-line to the Trigger. Now duplicate this ExplosionEvent 2 times. Spread them out a bit like I did. Now we need to make a slight change in each of these 2. Open 1 of the duplicates up and change the ExplosionChain->DelayTime to 0.4 and the size to 1.0. Now open up the other duplicate and change the ExplosionChain->DelayTime to 0.5.

Now for the tricky part! (heh!) Dispatchers!

The concept behind a dispatcher is that you can save a lot of red lines on the screen :) I"ll tell you what to do and then use what we"ve done to help me explain what a dispatcher is exactly, but by then it should be obvious.

Ok, select a Dispatcher from Classes->Triggers->*Dispatcher and place 1 in the hallway. Now under the Dispatcer"s Properties set the Events-> Event: to "MyDispatcher" (again this could be anything), and Tag: to "MyTagName". Under Properties->Dispatcher you should see OutDelays, and OutEvents. Click on OutEvents. You have 7 events per dispatcher that you can assign and if you need more just fill one up with 6 events and make the 7th a call to another Dispatcher. Ok from 0 to 7 in OutEvents, fill in the following info: lights1, lights2, lights3, lights4, lights5, onlights1, onlights2, onlights3. Lights1 should be the 0 value and onlights3 should be the 7th. What are all of those values?!? Well, when you light your hallway these will be the Tags for the lights so you can control if the lights are on or off or not! Now, go to OutDelays: and make the values for 0-7 be 1.00. This value is in seconds and represents how long it should pause between excecuting events. like say I wanted there to be a 4 second pause before it executed lights1 and lights2, I would set OutDelays 0 to 4.00. Get it? Good. By changing all the values to 1.0 you are saying you want a 1 second delay between each of the lights turing on.

Ok, now we need to place lights in the map. I want you to place them in the same areas I did in my side of the map. BUT WAIT! Do NOT place ordinary lights! You MUST go to Classes->*Light->*TriggerLight (now there are two of these, one with a dash, and one with out, it doesnt matter which one you choose, but for the sake of continuity, choose the one with the dash next to it). Now place a bunch of these lights in the same places I did. It"s best to make one, put it where it should be near a torch, and then duplicate it and place it where it should be on the torch arcross from it. Before you do any duplicating though, make a master torch to make your duplicates from, and copy the LightColor values I have on my lights and the Lighting values so yours can be that nice firey orange with a wavy effect. You must set these values for all of the torches (or just that one master torch if you are going to be duplicating it): Under Properties:

  • Object->InitialState: "TriggerTurnsOff" (this setting is saying that we want the light to be on, and then be turned off when we activate the trigger).

  • TriggerLight->bDelayFullOn: True

  • TriggerLight->bInitiallyOn: True (here we are saying we want the light to start off on, this corressponds to the InitialState of the trigger that we set under Object)

  • TriggerLight->ChangeTime: 0.0

  • TriggerLight->RemainOnTime: 0.0

Then select those two lights and duplicate a few times and place them on the torches. So you should have 10 TriggerLights each infront of a torch (like on my side of the map). Now select all 10 lights and with them all selected, open up the Properties for the lights and under Events, change Event: to "None" and Tag: to "lights". Look at the map and see that the torches are divided up into 5 pairs. Well, each pair will be controlled by one of the 5 values from our Dispatcher! (Confused yet?!). So select the first two torches (and i mean torches facing each other), and under Properties Events: change Tag: from "lights" to "lights1". Then select the next two torches and change their tag from "lights" to "lights2" all the way up until you have a pair with "lights5" as a Tag.

Almost done...

Now make a nother TriggerLight by duplicating one of the torches...This time in properties change a few values as follows:

  • Events->Tag: onlights

  • Object->InitialState: "TriggerTurnsOn"

  • TriggerLight->bInitiallyOn: False

Now, in my map, these lights were the red and blue ones that turned on after the map was dark. So duplicate the light you just made 5 more times and place it around the map in the same general area as I placed them on mine (so 3 pairs of lights across from each other). Now like we did before with the torches, we need to set the tags of these 3 pairs to work with the Dispatcher that we setup. So select a pair of the two floor lights you just made and set the tag to "onlights1" and then with the next pair of floorlights set the tag to "onlights2", and finally, to the third pair of floor lights set their tag to "onlights3". You can now select all 6 of those floor lights and add whatever kind of pulsating effects or colors you want, or you could just copy my settings ;-)

You should be ready to rock! Rebuild the map, and make sure the PlayerStart joystick icon is on your side of the map. Now play that sucker and pray it worked :)


SpecialEvents

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: maverick@planetunreal.com

Forward:

After helping numerous people in irc.enterthegame.com's #unrealed on the subject of SpecialEvents, I decided to write a small tutorial on how they work and how to use them.

Abstract:

This tutorial will teach you what the SpecialEvent Actor does, and how to use it.
This will not teach you how to create a flyby.

Assumptions:

I assume that you have intermediate knowledge about UnrealEd2.0.

Tutorial:

Introduction:

Was there ever a time when you wanted to make an electrical beam destroy someone and splatter their carcass? Or maybe cause a sound to be played when a person walks by? Here's how.

Part 1. What is a SpecialEvent?

A specialEvent is a trigger that causes a special effect to occur.

Part 2. The features of a SpecialEvent.

The SpecialEvent is located under Triggers.
The features of a specialEvent can be found in the SpecialEvent properties under Object:

PlayerPath: This is a complicated feature of the SpecialEvent, but basically, what it does is sets the instigator (The actor that triggered the event) on a spline path around the map. The spline is used in flybies, it is the path that the instigator travels on. We will not go over this feature in this tutorial, that will come later, when I write a tutorial on how to create flybies with ease.

PlayAmbientSoundEffect: A strange feature, I still haven't figured out it's use. You set the sound in the Sound tree, when you enter the game, it's playing the sound, but when you trigger the SpecialEvent, both you and the SpecialEvent play the sound.

PlayersPlaySound: This causes the instigator to play the selected sound. The strange thing is, as you walk away, the sound stays with you, and gets annoying.

PlaySoundEffect: Simple effect. When triggered, it causes the SpecialEvent to play a selected sound.

KillInstigator: Kills the instigator who triggered the specialevent. This does not damage the carcass.

DamageInstigator: Does a X damage to the instigator, where X is the value you set. You set the damage value under the SpecialEvent tree. The more damage you do above 100, the more damage it will do to the dead body, and can cause it to destroy the body. (Make the guts fly everywhere).

DisplayMessage: Displays the message you typed in. You type the message in under the SpecialEvent Tree. Selecting broadcast causes every player to see the message, not just the instigator.

Using a SpecialEvent.

Setting up a SpecialEvent is quite easy. First, you add your SpecialEvent and give the tag a name.Then, add a regular trigger, and put the SpecialEvent's tag name in the Trigger's Event name.
Now, set the SpecialEvent's InitialState, and your ready to use it!

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


Interpolation Points

by: Machismo a.ka. The Indian Fakir
cool_machismo@yahoo.com

WHAT´S UP WITH THIS?

There are a 101 things that you can use special events. They allow you to do some fantastic stuff. If you were to place a special event (located under Triggers for those who didn"t know) in your level and go to its advanced properties and check out Object|Initial State it would give you a list of what you can do with the special events. This tutorial aims to explain all but two of these. The special event almost always gets triggered by a trigger - I have never come across another way - this doesn"t count FortStandards used in assault. The way to do this would be to set the event of the trigger and the tag of the special event to the same. Ok, Lets get on with it.

SPECIAL EVENT INITIAL STATE LIST:

PLAYER PATH:

Not much to say about this other than read my interpolation tutorial. It is used only in conjunction with interpolation points. It is used to create opening / ending sequences but that"s another tutorial altogether. Anyway probably less than .5% of people will want to create those sequences - if at all such a large number exists.

PLAYERS PLAY SOUND EFFECT\ PLAY SOUND EFFECT:

The next two under initial state may look the same ....... or they could be different. Yes, they are different but in a very subtle way which is why I"m explaining them under one place. The difference is that Players Play Sound Effect "affects" all the players in the map. This means that no matter where the player is on the map he will here the sound. It will continue to play even if the instigator dies or there is no one in the vicinity of the special event. It will continue to play for the remainder of the time until the time or frag limit is used/reached. I prefer to use these only in assault maps at the very end and use stuff like sirens as the sound. On the other hand Play Sound Effect will play and be heard only in the vicinity of the special event (naturally this will be affected by the sound radius).

HOW TO SET THESE UP: Ok now that you know the difference setting it up should be a snap. The event of the trigger and the tag of the special event should be the same. Under Object|Initial State choose what suits your need. Expand special event and set bBroadcast to true so that players hear the sound. Still under special event set the sound to what you want. If you chose play sound effect you may want to change the values under sound - radius, pitch, etc. You may also want to change sound volume if you used Players Play Sound Effect - obviously here the radius does not matter since players will hear it anyway.

KILL INSTIGATOR:

t does just what the name says it kills the person who triggered this event immediately without a time delay. You use this in special situations (haha that"s what this tutorial is about) not covered by zone markers like - lava, slime, nitrogen, etc. For example if you set up a lava bed and make it into a lava zone if the player were to jump into it because of the lava zone he would be killed instantly. Use this instigator in situations not covered by the available zones - like space.

DAMAGE INSTIGATOR:

Unlike the kill instigator initstate the damage instigator kills the player slowly - like water - the difference being that the player can escape damage by stepping out of the radius of the trigger or getting killed altogether. Set it up as you would normally. Under special event|damage give the amount of damage per second that you want to be caused to the player. If you want the player to be killed slowly you can use 10 which is a nice value and some very high number to kill him off instantly. Under damage type you can use the standard types of damage by entering fell, corroded, burned, etc. bPlayerViewROT if set to true means that the player can rotate and look around while being dealt damage - say while falling from a cliff.

DISPLAY MESSAGE:

On being triggered it causes only a message to be displayed on the screen. If you want all the players including you to see it don"t forget to set bBroadcast to true under special event and give the message that you want to be displayed on the screen in the message box.

GENERAL SPECIAL EVENTS NOTES

Don"t confine yourself to one initstate. For example you can have a trigger set off the special event with its initstate at player play sound effect, give a message under special event and and a damage amount, set bBroadcast to true that way you shove three steps into one.

The more mundane uses of the special events are usually done in Assault. You can have a message displayed on the screen after a certain point. What I mean to say is that if you have a huge level and if you want everyone to be aware that the attackers have crossed a certain point yet not make it into an objective then special events is what you need.

One thing people forget on making "kill instigator events" for things like falling off a cliff and what not, is to set the proper collision radius of the trigger. I cant give you an exact number as it depends on your level but usually its a value above 1000 or something nice and big. I usually use something like 20000 for cliffs - but the number for your level can only be arrived at by experimentation. Another nice use of special events is to use it for quake 3 arena style jump pads - you can use the play sound effect whenever someone takes a jump. I think you"ve had enough of my rambling................... for now.


Using Team Triggers

By: astro

astro@planetunreal.com

UED Resource Lab

Team Triggers are a great way to make sure only a certain team can activate whatever it is you want to trigger. I am a Capture The Flag fanatic so when I make a CTF level the use of Team Triggers is almost a must. If you have ever played Team Fortress Classic then you know what I mean.

This tutorial is going to cover Team Movers. The specific type of mover is a door. I have created a test map so you can follow along. This is very easy to do so here we go:

I made rooms connected by a door that we are going to trigger using the TeamTrigger which is located in the Actor Class Browser under Triggers. The exact path is Triggers>Trigger>TeamTrigger. Take a look at this pic:

This door will be for the Blue team to access. I set the Tag under Events to "BlueTeam". Under Object, make sure to set the InitialState to TriggerControl. Now to set the properties for the trigger which will activate the door:

The Event for each team will match the tag of the door.

The Tag for each team will indicate which team the trigger is for.

The Team option under TeamTrigger will reflect the tag for the trigger. Blue team is 1 and red team is 0.

The TriggerType should be changed to TT_PlayerProximity.

Change the CollisionRadius for each trigger as I have above.

Once you set these options you will notice a line attaching each trigger to the door. That means that the Tag of each trigger matched the Event of the door. Now here is the setting that makes it all work properly. If each team can open the door because the Tag matches the Event we must change the Radius of each trigger so that only the blue team can access the door from the outside! Look at the pick below:

To view the radius of each trigger in the top down view, right-click on toolbar on the top of the top down viewport and browse to Actors then Radii View.

Room A is where we want the radius for the blue team's trigger to extend to. Notice that the radius for the blue team trigger goes from room B and into room A. This is because the radius is set to 300.

Now any blue player in room A can open the door by walking within the radius of the trigger and gain access to room B!

The Red Team trigger is set to such a small radius because you dont want that team to access the door from the outside. In the game there is a chance a red player can run into the room while a blue player is in it. If the red player kills the blue player he can get caught in the room and not be able to get out. Placing the trigger with a radius so small next to the door on the inside will at least allow the player to leave the room. That is the purpose of the second Red trigger.

If all went well and you followed this tutorial you should now have a door that will only open up for the blue team. Use team doors in your maps!


Triggers Class Reference

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Contents:

BioFear | CodeTrigger | Counter | Dispatcher | DistanceViewTrigger | ElevatorTrigger | FadeViewTrigger | FatnessTrigger | FearSpot | Jumper | Kicker | MusicEvent | RoundRobin | SpecialEvent | StochasticTrigger | TranslatorEvent | Trigger | TeamTrigger | TimedTrigger | ZoneTrigger | TriggeredDeath | TriggeredTexture

Introduction

First a bit of jargon:

Actor: any object within the game, including brushes, triggers, weapons and players

Pawn: any moving creature, including monsters, players and bots

Player: just real-life players

ScriptedPawn: basically just monsters

Touch: means this trigger is triggered by a pawn running into its collision cylinder (formed from the collision radius and collicion height)

Event: most triggers use the Event field to trigger another event

Tag: the name of the trigger, only important if it is triggered by another trigger

Each trigger has a number of keys next to it to signify a number of things:

UT: available in Unreal Tournament only (does no mean all triggers are useful in UT)

TC: triggered by pawn contact

TG: triggered by another trigger

The most basic trigger is Trigger. Check this one out first.

BioFear: UT, TC
Bots will fear randomly fear this spot dependant on their skill level. The CollisionRadius is reduced each time it is triggered by 25 until it is under 120 and then destroyed.
Parameters

bInitiallyActive:

whether the BioFear is initially active or not.

[^Top]
CodeTrigger: TC

See CodeMaster for a full run down of what the CodeTrigger does.

Parameters

Event:

tag for the ElevatorMover to trigger

Code:

tag of this CodeTrigger

CodeMasterTag:

tag of the code master

[^Top]
CodeMaster

The CodeMaster and CodeTrigger are used when you wish a number of things to be triggered in sequence. For example 3 triggers, say 1, 2 and 3 that open a door. However only if you press them in the following order does it work, 2, 1, 3.

The ElevatorMover is the 'visual cue' that a CodeTrigger has been triggered.

There is however a 'race' condition which means that things do not reset quite how they should.

Each CodeTrigger should have the CodeMasterTag set to the tag of the CodeMaster, Event set to the tag of the elevator mover and Code set to the sequence number (from 0 up).

The CodeMaster should have MainEvent set to the event to trigger on success, the OrderCode array set to the correct order of the CodeTriggers (e.g. 1, 0, 2), the MoverTags array set the the movers tags corresponding to each CodeTrigger and the NumElements set to the number of CodeTriggers you have.

Parameters

OrderCode[6]:

array listing the correct order of up to 6 CodeTrigger tags

MoverTags[6]:

array listing up to 6 ElevatorMover tags to reset if the order fails

NumElements:

the number of CodeTriggers

MainEvent:

tag of the event to be fired when the order is correct

Example map

Working on it (anyone!)

Note
The race condition I mentioned earlier means that the last mover to be trigger during a incorrectly entered sequence will not move when the CodeTrigger for that mover is touched again. This however does not effect the success or otherwise of your triggering.
[^Top]
Counter: TG
A countdown trigger with optional text message displayed to the event instigator.
Parameters

NumToCount:

number to count down from (A normal trigger would be 1)

bShowMessage:

whether to display a message to the players

CountMessage:

the message to be displayed with each count. The string %i is replaced with a number string (‘one’, ‘two’ etc).

CompleteMessage:

the message to be displayed when the actor is triggered

[^Top]
Dispatcher: TG
A trigger which can trigger up to 8 other events with optional delays for each event. Must be triggered itself by another trigger.
Parameters

OutEvents[8]:

the optional 8 events to be triggered

OutDelays[8]:

the optional 8 delays for each event

[^Top]
DistanceViewTrigger: UT, TG

When triggered it triggers all pawns that are within its collision radius and collision height. It has no parameters apart from the Event->Tag for its name.

It is used in UT as an anti-snipper/snipper assist trigger. Put a trigger where the snipper will be and set it to trigger a DistanceViewTrigger where bots will be. Then when a sniper appears any bots within the collision radius of the DistanceViewTrigger will get a ‘nudge’ and are more likely to notice the sniper (See CTF-Face for examples). This can also be used in reverse to make bot snipers more likely to see enemy on the ground by putting putting the trigger on the ground and the DistanceViewTrigger at the snipe spot (see CTF-Face and AS-Overlord for examples).

So for example: If you have a sniper spot, and the sniper keeps sitting there and no-one ever notices them from the ground, put a trigger at the sniper point, put a distance view trigger on the ground (make its collision radius quite big if you like) and then when the sniper appears at the snipe point the bots will notice them and attack if they are not doing something else.

Example map

TUT-Trig-DistView.zip

[^Top]
ElevatorTrigger: TC
When triggered by the usual array of Player/Pawn/Class/Any/Shoot (See normal trigger for fuller explanation) it moves an ElevatorMover to a specified keyframe.
Parameters

bTriggerOnceOnly:

true if the trigger can only be triggered once

ClassProximityType:

used with the TriggerType of TT_CLASSPROXIMITY so it can only be triggered by this specific class

GotoKeyFrame:

the keyframe to move the ElevatorMover to

MoveTime:

the amount of time the ElevatorMover takes to move

TriggerType:

TT_PlayerProximity / TT_PawnProximity / TT_AnyProximity / TT_ClassProximity / TT_Shoot

[^Top]
FadeViewTrigger: UT, TG

This produces a ‘Flash’ which gradually fades. The size of the
            flash will move from FadeViewTrigger->ZoneInfo->ViewFlash till
            it is smaller than FadeViewTrigger->TargetFlash in
            FadeViewTrigger->FadeSeconds seconds.

The only place I could find this trigger is in the end sequence for AS-OceanFloor where the view fades to black. This uses all the default values with a FadeSeconds value of 3.

Parameters

bTriggerOnceOnly:

whether it can be triggered only once

FadeSeconds:

number of seconds for the fade to be over

TargetFlash():

the target flash vector

[^Top]
FatnessTrigger: TG
Changes the fatness of a tagged actor from one state to another in a specified time.
Parameters

FatTag:

tag of the actors to be changed

StartFatness:

initial fatness of the actor (normal fatness is 128)

EndFatness:

end fatness

ChangeTime:

time taken to move between StartFatness and EndFatness

[^Top]
FearSpot: TC, TG
This is a spot that all pawns will fear.
Parameters

bInitiallyActive:

whether the spot is initially feared.

[^Top]
Jumper: TC
This will only affect ScriptPawns (i.e. monsters). It basically sets the monsters Z velocity to Jumper->JumpZ. The Movement->Rotation also affect the monsters rotational velocity and set its DesiredRotation.
Parameters

bOnceOnly:

only triggered once

LimitedToClass:

limits it to a specific class of monster

JumpZ:

amount of Z velocity. If 0 then it defaults to 100 (ish..)

[^Top]
Kicker: UT, TC
Similar to the Jumper but affects all pawns. Also sets all direction velocities, and not just Z.
Parameters

KickVelocity():

X,Y,Z for the velocity to add to pawn

KickedClasses:

classes which are effected by the Kicker (blank for all)

bKillVelocity:

if true then sets pawn velocity to zero before adding KickVelocity. Otherwise only Z velocity is reset and X and Y are added to the KickVelocity

bRandomise:

randomises the KickVelocity

[^Top]
MusicEvent: TG
Pays the specified music to one or all players.
Parameters

Song:

music from the browser. If blank defaults to the song for the level

SongSection:

section of the music

CDTrack:

CD track to play

EmusicTransition:

transition (to/from?)

bSilence:

if true then SongSection and CDTrack are both set to 255 (?)

bOnceOnly:

triggered only once.

bAffectAllPlayers:

if true then music played to all players, if not then only triggering player.

[^Top]
RoundRobin: TG
Each time this is triggered it triggers then next event in a list. It can also loop back to the beginning
Parameters

OutEvents[16]:

events to be triggered

bLoop:

if true then it loops back to the first event after triggering the last

[^Top]
SpecialEvent: TG

This event does a large number of very interesting things.

Firstly it can display a message to the triggering play or if bBroadcast is true then to all players.

The rest of the actions depend on the InitialState:

  • DisplayMessage: only display the message
  • DamageInstigator: Display DamageString to players and damage any pawn by the Damage amount.
  • KillInstigator: Kill the pawn, registering it as a death of type DamageType. Display message DamageString
  • PlaySoundEffect: plays the sound in the Sound parameter
  • PlayersPlaySoundEffect: plays the sound effect only the players (don’t know how this is different from above, presumably monsters wont react to this sound)
  • PlayAmbientSoundEffect: sets the triggers ambient sound to the AmbientSound parameter
  • PlayerPath: Works only when Level.NetMode = NM_Standalone (i.e. Single Player only). Moves the player along the InterpolationPoints with tag of Event->Event
  • Parameter bPlayerViewRot seems to be ignored.
[^Top]
StochasticTrigger: TG
A random trigger generator. It has two InitialStates, AlwaysActive and TriggeredActive. The latter means it must be triggered before it will genereate any events. It randomly triggers one of up to six events.
Parameters

Events[6]:

up to six events which will be chosen to trigger.

triggerProbability:

each time it tests itself this is the probability that an event will be triggered. (Between 0 and 1)

minReCheckTime:

minimum time between tests

maxReCheckTime:

maximum time between tests

Example map

TUT-Trig-Sto.zip

[^Top]
TranslatorEvent: TC, TG
This is used in single player Unreal maps. If you have the translator then a message appear in it for you. If bTriggerAltMessage if true then the translocator is reset with the AltMessage.
Parameters

AltMessage:

alternative message to be swapped in

bTriggerAltMessage:

if true, after the trigger is triggered then TranslatorEvent is reset the AltMessage is displayed

bTriggerOnly:

no know effect

Hint:

no know effect

M_NewMessage:

message displayed when the new message arrives

M_TransMessage:

message displayed when the message arrives and is not new

ReTriggerDelay:

delay until trigger can be triggered again, should be just greater than zero so is not triggered twice with one walk through.

[^Top]
Trigger: TC, TG
The mother of them all, the default type of trigger.
Parameter

bInitiallyActive:

whether the trigger is initially active or not (i.e. whether another trigger needs to trigger this trigger before it can trigger anything else...)

bTriggerOnceOnly:

whether the trigger can only be triggered once.

ClassProximityType:

only the given class can trigger then event (if TriggerType is TT_ClassProximity)

DamageThreshold:

how much damage has to be inflicted before the it triggers the event (if TriggerType is TT_Shoot)

Message:

message to display when triggered

RepeatTriggerTime:

if the pawn who triggered the trigger stays ‘touching’ the trigger then then after this time repeat the event.

ReTriggerDelay:

amount of time before event can be triggered again.

TriggerType:

TT_PlayerProximity / TT_PawnProximity / TT_ClassProximity / TT_AnyProximity / TT_Shoot

Example map

TUT-Trig-Trigger.zip

[^Top]
Teamtrigger: UT, TC, TG
As above but only triggered by for teams not matching Team. Also has bTimed parameter which seesm to turn it into a timed looping trigger. (****)
[^Top]
TimedTrigger: UT, TC, TG

Triggered after DelaySeconds, doesn’t work in Deathmatch games which require you to press a button to signal you are ready (Tournament type)

If bRepeating is true then it also repeats every DelaySeconds.

Parameters

DelaySeconds:

delay in seconds before triggered

bRepeating:

if true then triggered again in above number of seconds

[^Top]
ZoneTrigger: TC, TG
This triggers all zoneinfo actors with a matching ZoneTag. Good for turning on PainZones
[^Top]
TriggeredDeath: TC
This kills any player who touches it with a screen flash and sounds
Parameters

MaleDeathSound:

sound to play if player is male

FemaleDeathSound:

sound to play if player is female

StartFlashScale:

[^Top]
TriggeredTexture
This replaces the DestinationTexture with the first value in the Textures[] array and then each time it is triggered it moves to the next texture in the Textures[] array.
Parameters

bTriggerOnceOnly:

if true it can be triggered through all the textures to the end and then stops. If false it will loop back to the beginning.

DestinationTexture:

texture to be replaced

Textures[10]:

array of ten textures to rotate through. The first texture[0] will be the one seen at the start of the game.

Example map

TUT-Trig-Texture.zip

[^Top]


Zones

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    Forward:

    I have had a few people ask me about the proper way to create zones so I best make a tutorial about it huh?

    Abstract:

    This will explain (in detail) how zones should be used, what they can do and how to set them up properly...

    Assumptions:

    I assume that you have a decent knowledge of the editor, and how to create a basic level.

    Tutorial:

    Introduction:

    Zones can be quite tricky if you don't really understand how they work, so if we explain them and how they work, life should be a WHOLE lot easier.

    Setting the scene:

    Zones are used by the editor to know when to stop filling an area with water, they also tell the editor when to make changes to the ambient lighting in an area. They can be used to accomplish a million things, but to do so we must understand how they work. A zone is simply an "invisible wall" that does not affect the player, ie doesn't stop them or anything like that, but tell the editor to stop doing whatever the last zoneinfo told them to do. A zone is automatically placed for example when you use the "Add Special > Waterzone" button. This not only adds in a sheet that can be textured, and made to look nice, and the rest of it, but places an invisible zone barrier, so when we place the "Waterzone Info" below the water line, the editor puts the water UNDER the shhet, then stops adding water to the rest of the room. You can set these barriers in pretty much any way you like, so if you want a complex waterfall, you can make it look really good by using a complex brush, then selecting "waterzone" and adding it in. A zone does not have to be a sheet! It can be any shape that can be made with the construction brush, although sticking to something that isn't too complex is normally a good idea...

    How to use zone barriers best:

    Technically you could set up a barrier wherever you like, but it is a good idea to be able to place them (assuming they are not a water zone ect) in a place where you will not readily be able to see both zones at the same time. I mean a good place for a barrier would be in a hallway, placed so that the player can see into either zone, but not both. This then stops any problems about Fog not being seen from afar or other problems that can occur. On this note, if you have fog that you would like to add in somewhere, then make sure that you set the barriers in a place where you will not be able to see the fog from. I mean, place the barriers around a corner for example, as when you set a zone to have fog in it, if you should be able to see the fog from afar, and the player is inside another zone, then they will see the light, but the fog will not be seen from the other zone EVEN if it should be in plain view - so keeping barriers around corners is a good rule of thumb to stick to...

    The best way to create the barriers:

    A barrier MUST completely fill the gap where you want it to be. This may sound silly, but most problems occur when a map editor places a barrier and it looks OK, but the editor keeps finding a TINY (It may not even seem to be there at all...) hole and assumes that it is not a barrier at all, so when you place a barrier, make sure that you create a sheet (or other shape) that is bigger then the area you want the barrier to be in, and INTERSECT it with the world. This means that the editor makes sure there are NO holes in it. This also is generally a better way, because it will make a smaller brush thus putting less load on the processor.

    Prefab zones:

    The editor comes with a LOT of pre-programmed zones, and for the most part, these will do quite nicely. There are "Water Zones", "Lava Zones" and a whole lot more. These should be allow you to create a fair amount. If you want to create a Fog Zone, then have a quick look at the "Fog" tutorial on this site, and it will tell you what you need to know. If you want to create your own settings for zones then I should have a tutorial posted on it shortly.


BB Drac - Unreal Tournament UED2 guide Zones explained

Zones Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Zones are used to divide a level into logical areas.

Two main reasons for you to take advantage of zones.
First of all it allow you to change the physics in one area of the level.
This could be everything like, water, lava, gravity, vaccum,
surface friction and so on.

The second reason is the framerate gain.
By dividing the map into logical areas you reduce the overall
processing time to calculate the visibility.

To gain anything from this, the zonportals need to be as small as
possible.
Placing them in hallways, doorways and windows might be the best option.

This is how a small level is zoned into two areas.
Screenshot
As you can see, each zone is shown with different colors.

To actually create a zoned area you need to physically seal off parts of the level.
Create a sheet and then select "Add Special Brush" and select "Zone Portal".
(If you create water you may use "Water" instead).

If you want to alter zone specific information you need to place a "ZoneInfo"
actor inside the zoned area.

There is a limit of 64 zones for each level. If this number is exceeded some
zones will be merged together.

In short you use zones for two reasons.
The first is to alter the physics in specific areas.
The second is to speed up the overall game speed.

There exist alot of pre-defined zones available for you to use.
They are found under "Info" and "Zoneinfo" in the actor browser.
Here is a list of the available:

ZoneInfo | Specific
CloudZone | Items will disappear in this zone, emulates a skyzone.
KillingField | This actor do not work (script is empty).
LavaZone | This zone emulates lava and will kill you within short (-40/sec).
LevelInfo | This is placed automaticlly by UED2 in the centre of your level.
NitrogenZone | Works/looks like water but player lose health (-20/sec).
PressureZone | When "triggered" anyone inside will be "depressurized".
SkyZoneInfo | Used to create a skyzone, used with "fake backdrop" textures.
SlimeZone | Like lave zone but a different look (-40/sec).
TarZone | Works like a waterzone but at a very slow moving speed.
TeleporterZone | Teleports the player (by associated teleporter) to a teleporter.
ToggleZoneInfo | This actor do not work (script is empty).
VacuumZone | Nearly instant death.
WarpZoneInfo | Portals, to seamless connect two parts of a level togheter.
WaterZone | Change from walk to swim mode and you will suffocate.

This list will show some of the properties you are able to alter:

Property | Specific
+LocationString |
ZoneName | Name that will show up at the scoreboard and comments.
+Reverb |
bRaytraceReverb | Not really sure what it do.
bReverbZone | Enables/Disables reverb in the zone.
CutOffHz | Sounds below this hz will not be included in the reverb.
Delay[] | Delay before 'echo' occure.
Gain[] | Volume gain when the appropriate 'echo' occure.
MasterGain | Main volume gain applied to each 'echo'.
SpeedOfSound | How fast the sound will be played.
+ZoneInfo |
bBounceVelocity | Don't think there is any code to support this property.
bDestructive | If true, gibs and carcasses will not lie around in the zone.
bFogZone | Enable/Disable volumetric light to be rendered inside the zone.
bGravityZone | Don't see the point as you can set gravity anyway.
bKillZone | I can't find any code for this property so I guess its not working.
bMoveProjectiles | If true, ZoneVelocity will also affect projectiles.
bNeutralZone | If true, player cannot be harmed by zone specific properties.
bNoInventory | If true, no dropped items can lie around in the zone.
bPainZone | If true all players will loose health each second.
bWaterZone | Fill the entire zone with liquid.
DamagePerSec | The amount of health lost each second if bPainZone is true.
DamageString | The death message to be used instead of type.
DamageType | How the screen and death message is affected.
EntryActor | Actor that appear when someone enter the zone (bWater=true).
EntrySound | Sound effect heard when someone enter the zone (bWater=true).
ExitActor | Actor that appear when someone exit the zone (bWater=true).
ExitSound | Sound effect heard when someone exit the zone (bWater=true).
MaxCarcasses | Max number of body parts that can be in the zone at one time.
MaxLightCount | Max of lights to use if MinLightingPolyCount > MeshPolyCount
MaxLightingPolyCount | The maximum of 'allowed' lit sides.
MinLightCount | Min of lights to use if MaxLightingPolyCount < MeshPolyCount
MinLightingPolyCount | The minimum of 'allowed' lit sides.
ZoneFluidFriction | Alter the friction while swimming inside the zone.
ZoneGravity[] | Alter the direction and strength of gravity in the zone.
ZoneGroundFriction | Alter the friction while walking inside the zone.
ZonePlayerEvent | This event is triggered if any player enters the zone.
ZoneTag | Don't really know what this is used for.
ZoneTerminalVelocity | Maximum falling speed, overrides gravity.
ZoneVelocity[] | Adds constant speed to all moving things in the zone.
+ZoneLight |
AmbientBrightness | The default light level in the zone.
AmbientHue | The default light coloring in the zone.
AmbientSaturation | The default light coloring in the zone.
EnviromentMap | Don't know what do.
FogColor | Don't know what do.
FogDistance | Don't know what do.
TexUPanSpeed | Alter the speed of all U-Panning textures in the zone.
TexVPanSpeed | Alter the speed of all V-Panning textures in the zone.
ViewFlash[] | Used with ViewFog to counter brightness (0 to -1).
ViewFog[] | Vector based increase of RGB brightness (0 - 1).

ZoneInfo priority:
Level properties is also treated as zone information and changes to it
will affect the entire level.
When you create individual zones you are able to use zoneinfo actors
to override the level properties inside that zone.
(LocationID will override the zoneinfo name.)

 Location ID:
When you are unable to use zones or zones is not needed you can use the "LocationID"
to change the shown name inside a zone.
This will only affect a small area which is specified with the location radius.

LocationID | Specific
LocationName | The displayed name.
Radius | The area affected by LocationID

The "locationid" actor can be found in the actor browser under "keypoint".

 Triggering zones:
By default you cannot trigger or alter the properties of zones.
The pressure zone however must be triggered to work.

What you can trigger is the property 'bPainZone'.
The only way here is to trigger bPainZone from false to true.
This can be done by any trigger.

When tracing the code (and checking other tutorials for zones) I see that
it connect with the property 'ZoneTag'.
No matter how I try to link triggers with zones I can only trigger the property
'bPainZone' from false to true.

 Pain zones:
By setting "bPainZone" true and any value you want in "DamagePerSec" you can
either cause or heal damage.
Positive values will cause damage, while negative values will heal.

If someone dies in the zone, the shown deathmessage will be out
from damagetype.
(This will only happen if they player dies because of the damage
inflicted from being inside the zone).

With some zones you can also use "SpecialDamage" and set your own
deathmessage with "DamageString".

If you set "bNeutralZone" true a player cannot be harmed while
staying inside the zone.
This ofcourse only apply to zone specific properties.
The player do not take damage from "DamagePerSec" or from suffocation.

 bWaterZone:
This property set that the entire zone should be filled with fluid.
From this point it is up to you to emulate what kind of fluid this
would be.
By using the properties for ViewFog/ViewFlash, ZoneFluidFriction and
DamagePerSec you adjust how the 'fluid' looks and feels from the inside.

For some reason entry/exit actor and sound is set even thought it says 'None'.
I am pretty sure it is possible to override with new actors and sounds if
you add them to the properties, but I have tried to remove it all without luck.

Might be able to place 'dummy' actors and sounds here to fix that.

 bFogZone:
This property will allow you to see volumetric fog while inside the
zone.
This do not affect the properties ViewFog or ViewFlash,
but fog created from lightsources.
(See my light and fog tutorial for more info).

If you have multiple zones and you should be able to see fog from
other zones you need to set "bFogZone" true for all.
Volumetric light will only be shown if the zone you are inside
have "bFogZone" true, even though the fog itself is located outside
the actual zone.

 Zone brightness (ViewFog/ViewFlash):
Zone brightness will set a default brightness to the screen.
This only affect the actual 'screen' and only while inside the zone.
(This is unaffected by bFogZone and cannot be seen outside the zone).

"ViewFog[]" sets the actual brightness and legal values range between 0 and 1.
What is set is the vector of RGB (X=R, Y=G and Z=B).

"ViewFlash[] counter the effects of "ViewFog[]" by softening the brightness.
Legal values range between 0 and -1.
The values used should be the opposite of the other set.
(Like ViewFog[0.2,0.2,0.2] and ViewFlash[-0.2,-0.2,-0.2]).

Normally this is used with bWaterZone to give the visual effect of underwater, lava,
slime and so on.
It can also just give the screen a default fog level if that is what you want.

 Zonelight:
Zonelight is default lighting inside the zone.
This is set with the properties "AmbientBrightness", "AmbientHue" and
"AmbientSaturation" which work the same way as regular lights.

This light affects all sides / polys inside the zone.
(Even sides with special lit flag).

This is very useful if you need to light larger areas and spare the
amount of light sources you put inside the map.
A drawback is that you wash out the colors and natural shadows.

 Max/Min Light Counts:
I am not really sure how or if this works but here goes.

The properties set the maximum and minimum amount of lights, inside the zone
to use if certain criteria is met.

If "MaxLightingPolyCount" is exceeded the minimum amount of lights to use is
set with "MinLightCount".
If the opposite occure, "MinLightingPolyCount" is higher than 'meshpolycount'
the amount of lights to use is "MaxLightCount".

If I understand correct, this is dynamic which means that the next frame may
be rendered different.
I think this counts towards meshes only, like players, pickups and decoration.

(I may be wrong on this one so don't hang me for it).

 CloudZone:
The cloudzone will kill all objects and pawns that enter the zone.
This can be used to remove projectiles (and players) that try to
go where they can't.

An example would be in aid with a skyzone.
The walls of the playable area are fake backdrops but can still be
hit by weapon fire.
By placing cloudzones you can prevent it from hitting the walls.

 KillingField:
The script for this zone is empty so it doesn't do anything.

 LavaZone:
Simply a zone filled with fluid (bWaterZone).
It have default ViewFog/ViewFlash.

Damage per second is set to 40 and damage type is "Burned".

 LevelInfo:
This is a special info actor that is placed automaticlly in the middle
of your map.
You open its properties by open the level properties from the menu.

This actor contain, not only regular zone info properties, but also
level related properties like music, opening screenshots and so on.

Do not add this actor yourself as it's allready done for you.

For more info on this subject, open my tutorial on level info.

 NitrogenZone:
Simply a zone filled with fluid (bWaterZone).
It have default ViewFog/ViewFlash.

Damage per second is set to 20 and damage type is "Frozen".

 PressureZone:
The pressure zone will stay inactive until someone triggers it.
When that happens, anybody who are inside the pressure zone will die
after the time specified with 'killtime', in seconds, have passed.

PressureZone | Specific
DieDrawScale | The size of your body (1 is normal).
DieFatness | Really don't know how to explain this.
DieFOV | Zooming of the screen (90 is no change).
EndFlashFog[] | Works the same way as the zones ViewFog[].
EndFlashScale | Don't know if this actually do anything.
KillTime | Time before you die (do not seem to work).
StartFlashFog[] | Works the same way as the zones ViewFog[].
StartFlashScale | Don't know if this actually do anything.

DieFOV is your 'Field Of View' and zoom in/out the players screen
(much like the sniper rifle) when dying.
Here is 90 the same as a normal screen and values below 90 will zoom
the screen away, while above 90 zoom the screen inwards.

FlashFog[], which works like the zone based 'ViewFog[]' is
used to alter the coloring of the screen while you are inside the zone.
It will change fram 'StartFlashFog[]' to 'EndFlashFog[]'.

DieFatness seem to squish your body down to a small ball.
You can see this if you play in third person view, but I don't know
if other players will see this.

The differance between Vacuum and Pressure zone is that pressure
zone must be triggered.

 SkyZoneInfo:
The skyzone actor do not have any additional properties so it basiclly
work as a viewport/camera for any walls you have set as "FakeBackdrops".

See my skyzone tutorial for more detailed info.

 SlimeZone:
Simply a zone filled with fluid (bWaterZone).
It have default ViewFog/ViewFlash.

Damage per second is set to 40 and damage type is "Corroded".

 TarZone:
Simply a zone filled with fluid (bWaterZone).
It have default ViewFog/ViewFlash and a very high fluid friction.

Staying under water for too long will cause drowning.

 TeleporterZone:
This zone will teleport any player that enters the zone to a destination
teleporter.
For this to work you need to associate the teleporter zone to a
source teleporter first.

This is explained in the teleporter zone tutorial.

 ToggleZoneInfo:
I guess the purpose of this particular zone was to have alternate
physical attributes to one zone and able to switch between them.

This is just a guess from my side as the script is empty and
do nothing.

I quote:
"// what the hell is this? this script doesn't even compile!"

 VacuumZone:
Players entering this zone will be killed unless they are able to
exit before they die.
The time it take them to die is set with "KillTime" (in seconds).

Note:
Even though the "KillTime" is located in the script and used, it seems
that no matter what value you set, players die after 2.5 seconds
anyway.

VaccumZone | Specific
DieDrawScale | The size of your body (1 is normal).
DieFOV | Zooming of the screen (90 is no change).
EndFlashFog[] | Works the same way as the zones ViewFog[].
EndFlashScale | Don't know if this actually do anything.
KillTime | Time before you die (do not seem to work).
StartFlashFog[] | Works the same way as the zones ViewFog[].
StartFlashScale | Don't know if this actually do anything.

DieFOV is your 'Field Of View' and zoom in/out the players screen
(much like the sniper rifle) when dying.
Here is 90 the same as a normal screen and values below 90 will zoom
the screen away, while above 90 zoom the screen inwards.

FlashFog[], which works like the zone based 'ViewFog[]' is
used to alter the coloring of the screen while you are inside the zone.
It will change fram 'StartFlashFog[]' to 'EndFlashFog[]'.

The differance between Vacuum and Pressure zone is that pressure
zone must be triggered.

 WarpZoneInfo:
I don't know enough about warpzones and not tested it enough.
However, what I know is that it will seamless connect two zones
togheter with both teleportation and visual.

This is done by setting "OtherSideURL" to the "ThisTag" of the other
warpzone and vice versa with the other.
(Very much like a regular teleporter).

"bNoTeleFrag" can be set to prevent telefrag when using the warpzone.

When creating the warpzone it is important that the zoneportal and zonearea
have the same size or you will get some weird HOM effects.

HOM effects can happen anyway and actually creating the warpzone is delicate.
If this happens just delete the zoneportals and add new ones.

 WaterZone:
Simply a zone filled with water.
It have default ViewFog/ViewFlash, entry/exit sound and actors.

Staying under water for too long will cause drowning.


deCyber Build Section

Zones

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Accompanied files : Zones.UNR

Contents

1) Basic_Zones
2) Zone_Info
3) CloudZone
4) Killing field
5) LavaZone
6) LevelInfo
7) NitrogenZone
8) PressureZone
9) SkyZone
10) SlimeZone
11) TarZone
12) TeleporterZone
13) ToggleZoneInfo
14) VacuumZone
15) WarpZoneInfo
16) WaterZone
17) Creating Zones

Introduction

Zones are an essential part of mapping as they have two main purposes. Firstly they enable you to create essential elements in you level such as water, lava and skies and secondly they increase the efficiency of a map by splitting it up into several sections.

At the moment, the Unreal engine only allows up to 64 zones, but you would have to make a
pretty big level to get that close.

1) Basic Zones
In order for you to understand exactly what a zone is, you’ll probably benefit from seeing it visually. Create a box in your editor, 256 x 256 x 256 (the default) will do just fine. (You can do this really quickly by clicking on the cube icon and then immediately on the Subtract icon - who cares about the bubbly texture!?). Create an entirely separate box just like it, a few squares away. You must make sure they’re not touching at all. Rebuild it (F8).
Because you’ve added no lights, both boxes should look completely dark in your 3D window.

Now, on the top of your 3D view you should see a selection of icons. Click on the "Zone/Portal" icon (the one I've ringed in the picture.

As soon as you do that, you will see
the two rooms become much more visible, and appear in two separate colors. The different colors denote different "Zones" and UnrealED will automatically sort out separate untouching areas into different zones.

Each zone that is created can have its own unique properties
which you can set as you need. (e.g. water, lava, pain)

The picture on the left is taken from the "ActorClassBrowser" and gives you a list of all the different types of Zones that UT can give you.

The "ZoneInfo" class itself can be used and can have its own unique qualities. All you need to do to create one of these environments is add it into your area. (choose one from the browser so that its highlighted, then right click somewhere in your map and choose "add … whatever it is" Whatever "color" this zone is placed into, it will add those qualities to that whole "zone". (You don’t need to have your window in "Zone view" to add this actor).

I will now deal with each zone in turn (the ones that I know that is):

2) ZoneInfo
Zone info is the basic generic item.
When added to your world you can give your "Zone" the following qualities:

a) Reverb: (gives that echo sound if you fiddle with the settings)
b) Gravity: (bounce around by changing the values)
c) Fog: set it to true and lights will then be able to produce that foggy effect.
d) Pain (give the damage factor a minus quantity and it turns into a heal zone)

3) CloudZone
I tried using this but didn’t have any success, I think its supposed to help swallow projectiles when you fire at the sky.

4) Killing Field
I have absolutely no idea but the title hints that its probably quite a dangerous zone!

5) LavaZone
This will turn your Zone into a deadly area, where the pawns health is reduced by a specific amount every second.
You can change the amount that it hurts by changing the number in the "ZoneInfo" property. It also produces a sort of reddish hue when you swim in it. Wearing an asbestos suit will prevent the player getting damaged.

6) LevelInfo
You’ll never need to use it, this is supposed to be the same as the menu option.

7) Nitrogen Zone
Like the LavaZone, but is designed to act as if its freezing you.

8) Pressure Zone
Kills a player but not without fogging things up and distorting their vision. It'll even allow the player to view the squished body at the end of it! All of the properties that make this happen can be adjusted in the "PressureZone" properties of this actor.

9) SkyZone
This is used to create a good sky effect in your level. See the tutorial on skybox for more details.

10) SlimeZone
Again, similar to the LavaZone, but the pain factor is not so bad, and there is a greenish hue when you swim through it. Wearing a toxin suit will perevent the player from being damaged

11) TarZone
Not very painful, but extremely annoying for the player. It dramatically slows down the players movement when they are swimming in it!

12) TeleporterZone
Unsure what this does, but it looks as though if the zone tag is matched with a tag of teleporter in that zone the entire zone will act as a teleporter.

13) ToggleZoneInfo
I imagine this enables zones to be switched from one type of zone to another, but have never used it.

14) Vacuum Zone
Similar to the Pressure zone - used by DM-Morpheus.

15) Warp Zone
This is a really cool effect. It enables a player to pass from one part of the level with a WarpZone to another WarpZone area somewhere else in the level, and you can even see into the other area before you go there!

For more details see the tutorial on TELEPORTERS.

16) WaterZone
As you would think, this creates an area you can swim in. If you stay in too long, you die from suffocation.

17) Creating Zones
Seeing that separate rooms are automatically classed as separate zones is fine, but how do you create more than one zone in one area? The answer is that you must place a "sheet" in your area that divides your room into two parts. This is where it becomes tricky. I’ll take you through it step by step with the basic principle;

a) Create a room say 1024 x 1024 x 1024 and add textures and lighting to suit. (See other tutorials if you’re not sure how to). Rebuild it and save it as something like "zonetest.unr".

b) Right click on your "sheet" icon (at the bottom, on the right of your left-hand tool bar) and a property box will
appear. Set the dimensions to 1040 x 1040 and make sure the "Axis" selection is set to "AX_Horizontal. Position your brush so that it overlaps your cube on all sides and is about 2 squares (x 32 units) from the bottom of your cube.

c) Choose a nice watery texture from the GENfluid texture file.

d) Now click on the "Add special brush" icon which looks like a blue square with another smaller dotted square inside it. You will see a box appear that looks like this:

e) Set it up to look like the example above simply by choosing "water" from the dropdown list in the "Prefabs" box. Then click on "Add Special".

f) You should see a nice watery sheet appear in your cube if you move your camera inside the box. You should also see a green brush appear on your 2D views (once you've moved the builder brush out of the way) but it isn’t a water zone yet. Rebuild and save. Check out your "zone/portal view" as described in section 1 and if all has gone according to plan, you should see your cube divided into two different coloured sections. These are your two zones. Now all you need to do is tell it what the zones are. If you don’t give UnrealED that information it will assign the properties to them that are given in your "level info". If it hasn’t split into two zones, then its likely that your sheet isn’t overlapping all the edges.

g) Remember looking at the list of zones from the browser section earlier on? Choose the "water zone" from there and add it to your cube. Make sure that it is well inside the lower zone in your cube. Rebuild and save once again, add lights and a player start and then give it a try. You should be splashing around nicely in knee high water!
That should be enough to get you started with zones.

EZkeel
(Simon West-Bulford)


Basic Zone Overview

By: astro

astro@planetunreal.com

UED Resource Lab

What you should know how to do:

Understand the basics of the editor.

This tutorial will teach you the fundamentals of Zones and how they apply when building with Unrealed.

Clicking on the Zone/Portal button [image] in any of the viewports of the editor will display by color all the different zones in your map. This is very useful to determine if your map is properly zoned and especially for troubleshooting zone problems. Clicking on the Build Options button [image] will bring up the following dialog box:

The Stats tab will inform you on how many zones the map currently has. The Unreal engine is limited to 64 zones. Any more than that will end up with all the zones merging into one - NOT a pretty sight! Each zone in your map has the benefit of being a unique area because you can change the properties of that zone. You can fully customize almost every aspect of the environment by the use of the ZoneInfo [image] which you add through the Actor Class Browser button [image] .

The ZoneInfo is located under Info>ZoneInfo. Highlight it with your mouse then in the 3d viewport right click to add the ZoneInfo. I have created a small basic level to demonstrate how to seal off and zone your map.

As you can see from this top down view there are two large rooms connected by a smaller room and are labeled A, B, and C. Currently only C has a ZoneInfo. Clicking the Zone/Portal button would show you that they are all the same color indicating they are in fact only one zone all adhering to the properties of the ZoneInfo in room C. I am going to create a sheet brush that has the exact dimensions of room B and add a zone portal on each side of the room to seal it off. The dimensions of room B are 512*512*512.The sheet brush is in fact a only a sheet so we will only need to worry about the Height and the Width..

Selecting AX_XAxis will rotate the brush so that you do not have to do it manually. Using every viewport, line up the brush so that it is water tight around the edges.

I personally like to pick a unique texture to use at this stage. Click the Add Special button and select the Zone Portal from the Prefabs drop down menu. I always select 2 Sided as well.

Once you click OK the zone portal will be put into place. Do that on the other side of room B and you will now have 3 distinct zones in all the rooms.

Remember to rebuild after adding the zone barriers. Then add ZoneInfo's to the other two rooms. Now you are ready to start editing the properties of your zones! One of the things you should do is name each zone with unique names. Right click on a ZoneInfo to bring up the ZoneInfo Properties dialog box. LocationStrings is where you would enter a name for your zone:

Only place portals in small areas so that CPU utilization is kept to a minimum. Large portal areas can slow down the game.

That is all you need to know to start working with zones. A map that is zoned well can make all the difference.


Zone Parameters

By: astro

astro@planetunreal.com

UED Resource Lab

What you should know how to do:

Understand the basics of a Zones. If not follow this link.

Zones can be completely customized. I will show you a few things that can be modified under the advanced properties of the ZoneInfo [image].

GRAVITY:

You can adjust the gravity on any axis: X,Y, or Z. When you load the editor the default direction you are facing is North.

Positive value for X=North

Negative value for X=South

Positve value for Y=East

Negative value for Y=West

X Axis is horizontally North and South. Y Axis is horizontally East and West. Z Axis is vertically up and down.

You can always get your bearings if you do not know which way you are facing by finding the camera icon in the top down view and pointing it to the right (north).

Adjust these settings in the ZoneInfo properties to change gravity. The ZoneGroundFriction can be adjusted to make the ground seem slippery. Try a value of -1000 and see what happens!

PAIN / HEALING:

Time to start hurting people. Adjust bPainZone to True and add a value to DamagePerSec.

Adjust bPainZone to True and add a Negative value to DamagePerSec and let the healing begin..

AMBIENT LIGHTING

Each zone can have it's own level of Ambient Lighting. Under ZoneLight, change the AmbientBrightness. This can help with some lighting and help eliminate dark shadows. Great for outdoor maps.

WATER:

Simply set the bWaterZone setting to True.

These are only a few of the zone parameters you can set. Crack into the properties of a zone info and experiment. Good luck!


Cool Zone Tricks

By: astro

astro@planetunreal.com

UED Resource Lab

What you should know how to do:

Understand the basics of UnrealED.

Understand the basics of zones. If not, click here.

I like this trick alot. It has been used in some levels I have seen on the net and thought it was worthy of a tutorial. We are going to make a zone that is able to push a player along a predefined axis at a predefined speed. We are going to make it look pretty cool while we are at it!

Fire up UnrealED and build a room that is 512*512*512. Add some lights and rebuild. Make a copy of the room and lights by highlighting them all and clicking Ctrl+W on your keyboard. Move the duplicate room next to the first room and rebuild. You should now have two indentical rooms next to each other. Now we are going to connect the two rooms with a cylinder tunnel. Click the Cylinder Brush button and size up the brush to match the distance between the two rooms. Once the brush is in place, subtract it using the Subtract button. Here is an example:

Try to have the two rooms a good distance apart for a better effect. If you are wondering what all the brown is on the floor in the right room I added a bunch of power-ups and weapons just for fun :) Now let's use a Sheet Brush to seal off each end of the tube. Remember that you can use a regular sheet brush to seal off the end of the cylinder even though they are not the same size. In some instances you will get a HOM (hall of mirrors) effect as a result. If so you can try deleting the brush and start over or move its position on the grid and then rebuild.

I thought adding a texture on the sheet brush would add a nice effect. I chose Fibre13 from the GenFX texture pack. Now click the Add Special button and this dialog box will appear:

Select Zone Portal from the PreFabs drop down menu. Make sure that Transparent, Zone Portal and 2 Sided are checked and click OK. Seal of both sides the same way:

While we are visually spicing things up let's put a cool texture on the inside of the tube and set it to pan in the direction we are going to shoot through. I chose Spacey from the GenFX texture package.

Select every surface in the tube and apply the texture. While they are all still selected, rotate the texture right right clicking and selecting Surface Properties. Browse to the Alignment tab and rotate the texture 90 degrees. On the Flags tab put a check next to U-Pan and Unlit. Rebuild.

Nice! Now the tube is sealed off at each end with a sheet brush and textured. Now I want to shoot from one end to the other as soon as I enter it. This is a simple process. Add a ZoneInfo into the tube. It is located in the Actor Class Browser: Info>Zoneinfo . Lets look at some properties:

I adjusted the Z axis of the ZoneGravity section so that a player in the game will have a smoother ride when shooting through the tube. I kept the default ZoneTerminalVelocity at 2500. The ZoneVelocity is the variable that actually pushes a player in any direction you specify.

X Axis is horizontally North and South. Y Axis is horizontally East and West. Z Axis is vertically up and down.

Now that you understand that you can set the ZoneVelocity. Depending on which way your map is flowing, it may need to be a negative number. I set mine to -8000. I really want to fly through there! I also changed the ZoneGroundFriction to zero just to be safe. Another setting is bMoveProjectiles. Set it to True if you want weapon discharge to be shot through the tube.

One last thing. The speed at which the texture is panning on the inside of the tube is probably to slow. You can speed it up to better match the rate at which you are flung through the tube. In the Advanced Properties of the ZoneInfo look under ZoneLight. Change the value of TexUPanSpeed to 10. I know if you set it over 50 it gets a little buggy.

REBUILD. If all went well then you should be able to shoot into the next room. I copied one zone tube and turned it around so I could shoot back into the first room. The key here is to experiment and have fun.


Advanced Portals In UnrealEd

by: DaveA
Dave_Arendash@intuit.com

In this tutorial, you will learn something about zones, especially warp zones. Classic, beautiful examples of tricks you can do with portals can be found in maps such as deCyberEscher and TwistedCrypt. What you will find here will help you make maps like that, and stuff you may not have thought of.

Glossary:

Symmetry: When stuff looks the same on one side as another, like a mirror image. You have mirror symmetry from right to left.
Asymmetry: When stuff doesn"t look the same from one side to the other, no matter how you turn it or mirror it.
Zone: In Unreal, a closed area defined by a Zone Info object.
Warp Zone: In Unreal, where crossing a zone portal takes you somewhere else. Unlike a teleporter, you can see through a warp zone portal into another area as if it were adjoining.
Warp Zone Portal: a flat sheet made in such a way that you can move, see, and shoot through it, which lets you go from one place to another separate place.
HOM or Hall of Mirrors: An effect in Unreal when playing, usually unintended, which is a lot like looking into a hall of mirrors. This is generally caused by sloppy level design.
Polyhedron: A 3 dimensional object. Like a polygon is a 2 dimensional object.
Regular Polyhedron: One with lots of symmetry. A cube is a good example.
Polyhedra: More than one polyhedron.
Centrifuge: A thing that spins, in this case to produce gravity. Often found at amusement parks.

What"s Wrong with this Picture?

Ever made a warp zone portal, only to find a hall-of-mirrors (HOM) or worse, crash? All is not lost. You could try deleting the portals and remake them from scratch. This is a last resort. Before you do, try these:

One

Assign a non-symmetric texture to your portal"s surface. The Engine group has some nice ones. I usually pick the guy with the arrow. Assigning this to your surface may show the problem: alignment.
The blue and green walls are zone portall brushes. Can you tell?
Ahh! See? Now you can tell how those surfaces are aligned. They aren"t.

All nice and aligned now.

You should do this for all your warp zone portals. Rebuild Geometry (F8) and play. NOTE: If you move, rotate, scale, or vertex edit the zone brush, you should repeat this, because those actions can mess up alignment.

Two

If that didn"t fix it, you may need to flip a zone portal brush. This means physically turning the polygon around. Choose one of the zone portal brushes, source or destination, that is giving you trouble. Read and follow Turning a Polygon Tutorial. Go to step one and try it again.

Three

If that still gives you garbage, chances are your geometry is off. Make sure the zone portals are the exact same size and shape. If they are symmetric, this will be easier. If they are not, you will have a hard time. You can use vertex edit with snap to grid to help you. If you are good with the rotate tool, you could try copy/paste, and then move and rotate that new brush to where it needs to be. Don"t forget to go to step one.

Four

If your portal seems right, but you are not crossing over to the other side, chances are the area behind the zone portal is not "deep" enough. Try making that roomier, but don"t change the portal"s shape, just how much is behind it.

Five

If that doesn"t work, there may be a possibility (someone correct me on this), that the area behind the portals must have matching geometry. Try making the area behind your portals symmetric, go to step 1.

Six

When you rebuild geometry, click on the BSP tab, and play with the settings there. You may get better results by setting Optimization to high, and cuts to low.

Seven

Try this: select your portal brush(es), hit Cut, then Paste and reposition them. For some reason, this sometimes helps. Perhaps it has something to do with the ordering of the brushes in the file or object hierarchy, and this will put them in as "newest"??? Clanless suggests: There is a much easier way to do this, right click a brush and you can set the brush to either first or last through the little order menu. Try both, can"t hurt.

Eight

From Wanderer: Try setting the zoneinfo"s property Advanced/bDirectional to True. This will give the Warpzoneinfo arrows. Then point the matching zones" arrows towards each other.

Nine

There are limits to what you can do with multiple portals touching each other. I have not fully explored this, but it seems that you must have some sort of opaque brush between them. Not to say that the opaque geometry must be opaque in the game, or that it has to have any real dimension. But it seems like there should be something there. Let"s take a for-instance: Let"s say you want a "room" which consists of 4 zone portals, each looks into another zone. If you have the 4 zone portal brushes just touching, forming a box (technically a 4-sided cylinder, assuming you have a normal floor and ceiling), this may not work. The reason is that if you step through one of those and look back, you would be able to see the "back" side of the one you went through, and possibly one of the other portals" backsides too. But, if you put 4 large pillars in, such that each zone brush touches two adjacent pillars, it would block the view of any other zone brush"s back side. Actually, what you"d want is 4 little rooms (closets) off of your central room. These "closets" will be empty except for the warp zone info token object. Now the magic: if you adjust the zone portal brushes so the coincide with the corners of these closets, you won"t see any closet parts at all, the "pillars" disappear, and you have what you were after, an area connecting 4 warp zones.

Alignment: Ah, there"s the rub!

Now that you (hopefully) have a working portal, you may notice that it looks more like a mirror, one you can cross through, like Alice through the looking glass. Or the world beyond may appear rotated or flipped. Well, this is all due to alignment. Choose a zone portal surface, hit F5 for the surface dialog, and hit the Rotate tab. Play with that. This can get your portals to line up straight, if that"s what you want, but perhaps you are doing something interesting, like deCyberEscher, and you want that "wall" in there to be a floor when you cross into it. Rotate! You might want to try playing with scale too. I don"t know that it will produce anything usable, but it can make some interesting effects. If you wanted to make fun house mirrors (software renderable too!) you could play with portals and put a transparent impenetrable wall in front of them.

Act Locally, Think Globally

Why limit yourself to orthogonal surfaces? I mean, floors, ceilings, and walls. If you angle the zone portal brushes, you can create curved surfaces, like planets and spaceship gravity areas. Just about anything you want.

Let"s say you want to create a planet that players can run around on. Your first thought may be to create a sphere hanging in a large space. Try that. You will fall off pretty quick. O.K., so you could create some zones, and set the direction of gravity to always point toward the center of that sphere. True, but the catch is, there is only one "up" in the game. I"d hoped that setting the rotation of the zone info would affect the "up" orientation, but I could not get that to work. If you know how, let me know (see tip 8 above for a possible clue). So, let"s say you do that anyway, what would happen is you could sorta stick to your sphere, but you"d be "on your head" when at the "bottom" of it. If that"s what you are after, go for it.

To get a rounded surface where gravity points down and you are right-side up, you can make a bunch of areas, all connected by warp zones, and angle the zone portals to make the boundaries appear to curve. Some effects you can achieve: a planet surface, a centrifuge for space ships (those hamster-wheel things as in 2001: A Space Odyssee, Mission To Mars, Babylon 5, Ringworld etc.), Escher worlds, and things such as high-gravity barrel rolls and playing on the inner surface of a sphere or box or whatever.

This is three rooms linked end-to-end.

This is three rooms linked end-to-end.

RingWorld. A gargantuan hamster wheel in space.

You can just make one "room" and set the portals to reenter the room, and you"ll get cool effects, not very playable, but perhaps some sort of cheap hall-of-mirrors for a funhouse level or something. To get a believable playing surface, you should pick your geometry carefully. Symmetry is your friend, asymmetry is for the brave and foolish. For good planet surfaces, consider regular polyhedra, the Platonic solids come to mind. These are the Dungeons and Dragons dice you are all so familiar with: tetrahedron (4 triangle sides), cube (6 square sides), octahedron (8 triangle sides), dodecahedron (12 pentagonal sides), and icosahedron (20 triangle sides). Having done a cube by hand, I can tell you, this is not for the faint of heart, but the cube is the easiest one to do. You don"t have to stop there, there are many polyhedra that can work. I have a program that can read in a brush (such as these polyhedra) and produce "rooms" that can get you started. In case you haven"t checked the examples, what these planet "rooms" look like are basically cup shapes - smaller on the bottom, wider on the top, and zone portals from ground to sky, angling out. There are limits to what you can do, see below, The Outer Limits.

The good and bad. This is one room crosslinked to itself. The room was basically square, but the walls are not angled to 45 degrees, so the geometry is off. Looks somewhat spherical, but it"s not.

To get a centrifuge, you would angle the walls in, so the bottom is wider than the top. Then you can run up the walls and across the ceiling like nobody"s business. You may need something in the center, to hide the central junction of all those zone brushes. In the case of spaceship centrifuges, this probably is fine. For hollow structures, you may need to have something floating in the middle of the room, maybe a decoration or something really bright to help hide the solid bits. Examples: Hollow Earth (a sphere) or Ringworld (a cylinder), each could have a central "sun" to hide the central zone brush junctions.

Notice the guy on the wall. He thinks you are on the wall.

Worm Holes From (and To) Hell

You can have some fun with portals in tunnels, to make the near seem far, and the far seem near. Warp Zones are like wormholes - they let you cross space in nothing flat. But that can be reversed too. Let"s say you have created a planet, and want a short-cut from one side to the other. You could drill holes in two opposing rooms, and put a portal near the bottom of each, leading to the other.

Note the zone walls are angled 45 degrees

That blob way down there to the right of the green cross hair is looking back at you.

On the outside, the world is small. But the tunnel through the middle looks much deeper than it should be. This was to illustrate the good and bad of this trick. That tunnel can be very very long. You could put Hell at the bottom of each (design Hell in two parts), and the person could fall for a long time, zip right through the middle, and pop out the other side. Or stop in Hell and shoot some baddies. Now here"s some physics trivia questions: If you could put a hole right through the middle of the Earth, and safely go through it A) what is the force of gravity like at the center? B) How fast would you be moving when you got to the other side? C) How long would it take? Answers: A - zero, B) - zero, C) 45 minutes. The reason for A) is that at the center, the entire planet is pulling on you equally from all directions, summing to zero. So, if you are pulling this trick, you may want more than one zone in the tunnels, with zero in the middle, and normal at the surface. The reason for B) is that you accelerate toward the center, which means you decelerate as you leave the center, and your speed is back to zero by the time you get to the other side. C) is particular to the real Earth, you can do whatever you want. Note that unless you move to the side, you will fall back through, and keep doing this forever (neglecting wind and stuff). More trivia: if your hole does not go through the center, but, say, from New York to Los Angeles, the time is the same: 45 minutes.

The Outer Limits

Unreal/UT has a limit of 64 zones total. My guess is the LevelInfo is one of them. That"s not a lot, just enough to make a 12-sided or 20-sided world. Each area is one zone, and each edge is another. So for an icosahedron, you have 20 sides, each side has 3 edges. 20 x 1 + 20 x 3 = 80, too much! But you might be able to do something cheezy like link all the interiors with a "sewer system" of tunnels to create 1 zone for all interiors. This flys in the face of good level design, but it"s a shot. There are smaller polyhedra that would work, but are not as round. There is a football shaped 10-sided shape, and of course the octahedron, which is 8 triangular faces. 8 x 1 + 8 x 3 = 32, no problem. You can still make larger worlds using dodecahedrons and buckyballs, but the total number of areas will not cover the planet with unique areas. Meaning, "you" will appear more than one place in the world. For example, you could make a dodecahedron world using 6 areas instead of 12, (46 total zones), and link them in such a way as to look like it has 12, but it"s really 6. And if you do it right, "you" would always appear on exactly the opposite side of the "world". So, if you are on the north polar region, you are also on the south polar region, they are the same. This should be ok, because you shouldn"t be able to run into yourself. The only thing you might notice is that when you are running around the world, it"s only half as far to go until you end up back where you started. With larger numbers of zones, say, a 60-sided buckyball (soccerball), you might need to have 1/4 or 1/5 of the actual surface covered, I don"t know, you do the math.

However, Unreal/UT also has a 3 zone "see through" limit, meaning, you can see through the zone you"re in to the zone just past that, then the zone just past that, then the zone just past that, but you can"t see past THAT. At that point, you will see the texture on the zone portal. So, you can either limit the visibility of the zones, or use non-textured or otherwise invisible textures on the zone portals. Do that LAST as you will want to keep an eye on alignment all the way to the end. What you"ll be seeing then is the "closet" area past the zone, so again, be creative.

Limiting zone visibility is better and trickier and more fun. On planetoids, this means keeping the curvature up (small planet) or the "atmosphere" shallow. If you can jump high enough to see more than 3 zones deep, you"ll see the problem. So, don"t plan on putting in high sniper towers on small planets. Make the planet large enough so that even in the tower, the "horizon" is pretty far off. In centrifuges, I found that 7 is the limit on the number of segments if you can see them all. I use the "ceilings" to "create" a "structure" in the center. It looks like the hub of a wheel. This hides the problem behind this hub, so you can"t see it. If you are doing a large space station, like in 2001 (there is map 2001][ which does this I think), then you can have as many segments as you want, because you can only see into the two adjacent zones.

Many thanks to Art for pointing out these limits. Art says: "All ya need to do is subtract a few of "em in, toss in zoneinfos and warpzoneinfos, and detail to your heart"s content. I"m not really planning to make a level, just wanted to see a "round" world thing."

Skyboxes: Not so fast there, Sport

So you have created a sweet little planet, and now you want to place it in the cosmos. Fair enough. But before you make that skybox, which is a good instinct, let me point this out - rotation is a bitch. Unless you do a lot of tricks with the skybox, it won"t look right. Each area that makes up your planet has it"s own sky. At the "equator" the clouds, stars, etc., would be moving in a straight line, but at the "poles", they"d be rotating about the center. And in the middle latitudes, in a big wide off-center arc. You may have better luck animating each area"s sky surface textures. For a skybox to work that way, you might be able to make a roughly spherical "box" and then animate each surface in that sphere in such a way that it appears to rotate. But remember, there is only one "up", so only the top of your skybox would be seen, and it would be the same in every area. Note that if our first thought (to make a sphere in space and put gravity zones around it) might work with rotation nicely, if you could do that. But for now, good luck. You may want to stick with a static sky, whether you use a skybox or not. Please try, it would be cool.


Info Class Reference

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Introduction

This is a descriptive list of the Info actor class within the unreal script class structure. It is intended as a reference for level editors and is not intended for programmers or mod developers. However they may find it of some use, you never know.

The Info classes are used to hold information which is then made available to other classes, e.g. the LevelInfo class holds information about the current level being played, how long its been going, the name of the map etc.

Most of these classes are of no use to level editors at all, and will be covered very lightly. For some others, only the parent classes will be dealt with and these features should apply to all their children classes.

Quick Guide to acronyms and icons

UT: Unreal Tournament only

: Useful to level editors

CodeMaster | ZoneInfo | CloudZone | LavaZone | LevelInfo | NitrogenZone | PressureZone | SkyZoneInfo/RockingSkyZoneInfo | SlimeZone | TarZone | TeleporterZone | VacuumZone | WarpZoneInfo | WaterZone

: Some interest to level editors

GameInfo

: No interest to level editors, don't even bother, I know I wish I hadn't

BotInfo | ChallengeBotInfo | InternetInfo | Ladder, Ladder* | MapList | MeshActor | RatedMatchInfo, Ratedmatch* | ReplicationInfo | SavedMove | ScoreBoard | SelectionDude | ServerInfo | StatLog | TeamInfo | TestInfo | VoicePack | KillingField | ToggleZoneInfo

BotInfo:
Can be used to define the default bots to play on a level: Unreal level
[^TOP]
ChallengeBotInfo: UT:

Can be used to define the default bots to play on a level: Unreal Tournament level

Whether this overrides the settings in the ini file I do not know. I will find out.

[^TOP]
CodeMaster:
Used with the CodeTrigger to match a sequence of triggers. Check out my triggers reference. (p.s. I can’t actually get it to work anyway!)
[^TOP]
GameInfo:

This is the main class which contains all the sub-classes for the game types used in Unreal and UT.

You can force your level to load a particular game type by setting its DefaultGameType property in the LevelInfo properties to the game type of your choice. This can be useful when testing a level from within UnrealEd as will default to Single player if you are using Unreal, and Deathmatch if you are using Unreal Tournament.

N.B. If you do use this feature when developing your game it can be handy to take it out when you distribute, as people will be unable to use your level for other mods (such as infiltration) if you do not.

e.g. To set a level to be a CTF Level only, browse to CTFGame

(Info->GameInfo->TournamentGameInfo->TeamGamePlus->CTFGame). Then go to the level properties (Press F6) and go to LevelInfo->DefaultGameType and press ‘Use’.

[^TOP]
InternetInfo:
Connection information. Not really a lot of use for level editors, now is it.
[^TOP]
Ladder, Ladder*: UT:
Contains information used in Unreal Tournament to define the players/skins/names/maps etc for each of the ladders in the tournament
[^TOP]
MapList:
Contains information about the map lists used for each game type.
[^TOP]
MeshActor:
I believe it is used to show players etc in the Unreal menu system (i.e. when you are choosing which model to play with)
[^TOP]
RatedMatchInfo, Ratedmatch*: UT:
More information help about the ladder matches, which teams to use and how hard the level should be.
[^TOP]
ReplicationInfo:

Something to do with….err Replication ?

This is all mutator editors and programmers seem to go on about. Level editors ignore.

[^TOP]
SavedMove:
Where the engine holds information that your PC has yet to process, such as player movements etc. Again, level editors ignore.
[^TOP]
ScoreBoard:
Contains information and drawing instructions about the current scores to be shown on the scoreboard.
[^TOP]
SelectionDude: UT:
The selection and trophy dude!
[^TOP]
ServerInfo: UT:
Used to draw various bits of information from the GameReplicationInfo.
[^TOP]
StatLog:
Used to write the stats to ngStats and your local log files.
[^TOP]
TeamInfo:
Holds information about team names etc.
[^TOP]
TestInfo:
Epic must use these for something I guess
[^TOP]
VoicePack:

Holds information about the voices used, and text equivalent.

Check out http://www.unreality.org/playthis

[^TOP]
ZoneInfo:

This contains information about the current zone, such as gravity, fog details etc.

Follows are some of its tags and their uses.

Parameters

ZoneTag:

Used by zone triggers, to set a zone with DamagePerSec greater than zero to be a pain-zone. i.e to turn its damage on.

ZoneGravity:

The gravity of the zone, default is –950.

ZoneVelocity:

ZoneGroundFriction:

How slippery the ground is. Default is 8.

ZoneFluidFriction:

How ‘slippery’ water is (technical term is viscocity ;-). Default is 1.2

ZoneTerminalVelocity:

Maximum falling velocity in a zone. Default is 2500

ZonePlayerEvent:

Triggers all actors with this tag when the player enters the zone.

DamagePerSec:

The amount of damage per second to inflict to a player if this is a pain zone.

DamageType:

The type of damage to do to a player.

DamageString:

The string when some one is damaged.

MaxCarcasses:

The maximum number of carcasses in a zone. Default is 3.

EntrySound:

Sound to play when a player enters the zone (e.g. water splash)

ExitSound:

Sound to play when a player exits the zone

EntryActor:

Object to spawn when player enters the zone (e.g. a splash or ripple if a water zone).

ExitActor:

Object to spawn when the player exits the zone.

bWaterZone:

This zone is water filled

bFogZone:

This zone can contain fog

bKillZone:

Actor will die when entering zone. I don’t believe there is any code to support this though. Haven’t tested it.

bNeutralZone:

Player can’t take damage in this zone.

bGravityZone:

Use zone gravity (instead of level gravity).

bPainZone:

Inflict damage per second as above to actors.

bDestructive:

Destroys carcasses in the zone.

bNoInventory:

Inventory isn’t dropped in this zone (you don’t want that rocket laucher appearing to ‘float’ in space now do you.

bMoveProjectiles:

Adds the zone velocity to projectiles entering the zone

bBounceVelocity:

Do players bounce when they land in this zone? Cannot find any code references to this property.

MinLightCount:

Minimum number of lights to apply to an actor mesh. Default is 6.

MaxLightCount:

Maximum number of lights to apply to an actor mesh. Default is 6.

MinLightingPolyCount:

MaxLightingPolyCount:

ZoneLight

AmbientBrightness:

alters the ambient light color.

AmbientHue:

see above

AmbientSaturation:

see above

FogColor:

The color of any fog

FogDistance:

The fog distance?

I would just like to point out at this point that to implement fog in a zone it is best to set bFogZone to true and then add lights and edit the VolumeFog settings. Fog zones don't display bullet holes etc as well. Oh and you can't see the fog in a fog zeon from outside the fog zone.

TexUPanSpeed:

The horizantal panning text speed.

TexVPanSpeed:

The vertical panning text speed.

ViewFlash:

used with ViewFog to stop over-brightening. Values range from 0 to –1. Typically all values will be the same (e.g. (-0.5, -0.5, -0.5)) and should have a magnitude the same as the average magnitude of the values in ViewFog to stop the screen from changing brightness.

ViewFog:

vector of RGB values between 0 and 1, increases the brightness of the screen.

Reverb - (Thanks Hells Serpant6 and Hanh Court for this info)

bReverbZone:

Zone echos sounds if true.

bRayTraceReverb:

Will reverb off walls

SpeedOfSound:

how fast the sound will travel in units(either per second or per tick)

MasterGain:

??

CutOffHz:

how low the sound can get before it's no longer played.

Delay[6]:

A how long for the sound to come back (basically it just plays the same sound again at a different time).

Gain[6]:

Syncs up with the same Delay number, and acts the same way but increases the volume instead.

LensFlare

LensFlare[12]:

I don’t understand this.. apparently they are for licensees only, correct me if I’m wrong.

LensFlareOffset[12]:

ditto

LensFlareScale[12]:

ditto

[^TOP]
CloudZone:
A zone which when entered the player dies, and it is logged as a Fall death. Also bullets and rockets disappear into them. (Thanks to Hanh Court again!)
[^TOP]
KillingField: UT:
Has no difference to a ZoneInfo
[^TOP]
LavaZone:

A zone full of dangerous lava. ;-)

Has the following parameters different to a normal zone.

DamagePerSec=40

DamageType=Burned

EntrySound=Sound'UnrealShare.Generic.LavaEn'

ExitSound=Sound'UnrealShare.Generic.LavaEx'

EntryActor=Class'UnrealShare.FlameExplosion'

ExitActor=Class'UnrealShare.FlameExplosion'

bWaterZone=True

bPainZone=True

bDestructive=True

bNoInventory=True

ViewFog=(X=0.585938,Y=0.195313,Z=0.078125)

[^TOP]
LevelInfo:

This is the zone info which describes your level. There should only be one per level. UnrealEd creates it for you (Press F6). Some useful properties below:

Parameters

TimeDilation:

Normally 1 – scales real time passage

Title:

the name of the level

Author:

yourself

IdealPlayerCount:

The string displayed to show ideal player count

RecommendedEmenies:

no of recommended enemy bots (used in rated games)

RecommendedTeammates:

no of recommended team bots (used in rated games)

LevelEnterText:

Used in Unreal 1, text displayed when you start a level.

LocalizedPkg:

Package to look in for localized strings.

bLonePlayer:

No multiplayer co-ordination?

bHumanOnly:

Only allow ‘human’ pawns in this level

Audio

Song:

the song to play

SongSection:

the section of the song to play

[^TOP]
NitrogenZone:

A liquid nitrogen zone. This is a cross between a water zone, and a poisonous gas zone. You can travel faster in nitrogen than in normal water.

Has the following parameters different to a normal zone.

  • DamagePerSec=20
  • DamageType=Frozen
  • bWaterZone=True
  • bPainZone=True
  • ViewFog=(X=0.011719,Y=0.039063,Z=0.046875)
[^TOP]
PressureZone: UT:
Similar to the Vacuum zone, but dying Fatness can be set. See VacuumZone for more information about all other properties.
Parameters

DieFatness:

The fatness of a player when they die. Default fatness for a player is 128. Min values is 1, max value is 255 (so values less than 128 will make the player look thin, greater than 128 will make the player look fat!)

[^TOP]
SkyZoneInfo: Both / RockingSkyZoneInfo: UT:
Signifies that this zone is to be used as the sky. The RockingSkyZone also rotates, changing the view of the sky. If you select the FakeBackdrop property on a given surface texture, then when the player looks at that surface it will be as if they are looking at this zone from the position of the SkyZoneInfo.

Obviously settings such as friction and gravity do not make any difference.

[^TOP]
SlimeZone:

Another predefined pain zone, this time filled with slime.

Has the following parameters different to a normal zone.

  • DamagePerSec=40
  • DamageType=Corroded
  • EntrySound=Sound'UnrealShare.Generic.LavaEn'
  • ExitSound=Sound'UnrealShare.Generic.LavaEx'
  • EntryActor=Class'UnrealShare.GreenSmokePuff'
  • ExitActor=Class'UnrealShare.GreenSmokePuff'
  • bWaterZone=True
  • bPainZone=True
  • bDestructive=True
  • ViewFlash=(X=-0.117200,Y=-0.117200,Z=-0.117200)
  • ViewFog=(X=0.187500,Y=0.281250,Z=0.093750)
[^TOP]
TarZone:

This is a thick treacle zone. You move slower in a tar zone than you do in water, and you do not incur damage (unless you run out of breath!) unlike the Nitrogen Zone.

Has the following parameters different to a normal zone.

  • ZoneFluidFriction=4.000000
  • ZoneTerminalVelocity=250.000000
  • EntrySound=Sound'UnrealShare.Generic.LavaEn'
  • ExitSound=Sound'UnrealShare.Generic.LavaEx'
  • bWaterZone=True
  • ViewFlash=(X=-0.390000,Y=-0.390000,Z=-0.390000)
  • ViewFog=(X=0.312500,Y=0.312500,Z=0.234375)
[^TOP]
TeleporterZone:
Anything entering this zone automatically touches the associated teleporter
Parameters

TeleporterTag:

The tag of the teleporter the player is to touch.

[^TOP]
ToggleZoneInfo:

And I quote (from the UnrealScript code)

// what the hell is this? this script doesn't even compile!

[^TOP]
VacuumZone: UT:
Like a vacuum, the player will expand in size and then explode, cool!
[^TOP]
WarpZoneInfo:
Used for making portals and teleports to other warpzoneinfos and other levels and even other servers…. there are lots of tutorials out there on this one item alone.
Parameters

OtherSideURL:

The unreal URL of the level or portal. e.g. just the tag for a particular portal or more complicated for other levels. See some tuts on teleporters for more information.

ThisTag:

The tag of this warp portal

bNoTeleFrag:

Whether a telefrag is caused at the other end

Destinations[8]:

When triggered the OtherSideURL will loop through the destinations in this array.

[^TOP]
WaterZone:

This is a water zone ;-)

Has the following parameters different to a normal zone.

  • ZoneName="Underwater"
  • EntrySound=Sound'UnrealShare.Generic.DSplash'
  • ExitSound=Sound'UnrealShare.Generic.WtrExit1'
  • EntryActor=Class'UnrealShare.WaterImpact'
  • ExitActor=Class'UnrealShare.WaterImpact'
  • bWaterZone=True
  • ViewFlash=(X=-0.078000,Y=-0.078000,Z=-0.078000)
  • ViewFog=(X=0.128900,Y=0.195300,Z=0.175780)
[^TOP]


Adding Location Strings

ADDING LOCATION STRINGS TO YOUR LEVEL...

By: Sliencer

utcity@planetunreal.com

UT City

FOREWORD:

I am suspecting that you know how to set up zones using sheets and you know where to find zoneinfo's and add them to you level correctly.

DIRECTIONS:

Ever wonder how Epic added those little location identifiers that showed up when one of your teammates talk to you? Well here's how to make them. First, using a level you already have. Set up your zones using the sheet tool. Next add a ZoneInfo object into each zone. The ZoneInfo object can be found in Classes>>Info>>ZoneInfo. Now for each ZoneInfo you have go into their properties dialog and then click on the plus sign next to the attribute section entitled 'LocationStrings'. Now under ZoneName put the name of the area/zone that you want to call it. For example look below:

CONCLUSION:

Now you know how to add location strings into your level.

OTHER:

Questions/Comments email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


Provided by

 Textures

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

Forward:

I needed to have a texture of a particular texture to a level that I am working on, and after I did it, I decided to make a tutorial on the subject as it is quite simple, but not something that is easy to work out...

Abstract:

I wanted to have a particular texture (a shot of the moon, if you must know) for a skybox that I was creating, and when I worked it out - it was so cool, that I had to post a tutorial on it so other people out there could create them easily.

Assumptions:

I am assuming that you have a copy of paint program. I am using Paint Shop Pro 5 (and I will be referring to some commands that are in it). If you need a copy, then download it from www.jasc.com. But enough there, as long as you have a paint program that supports .pxc files (Zsoft Paintbrushes Ver 5) the you shouldn't have any problems.

Tutorial:

Introduction:

I will create a simple texture to start with, then make an actual picture out of a file that I already have.

Creating a simple color:

I always wanted to have a simple black texture for those little out of the way things, but there isn't one in Unreal, so let's create one. First open your Paint program, and create a new image. Make the image about 500x500. Now we could use it with a "plain" black, but that does look a little too boring, and doesn't draw nicely, so let's add a little noise - (choose image from the menus at the top of the screen, and select "add noise".) Now we don't want to add in too much, but just enough to make it visible as blemishes in the metal. When you have added the noise, make the image grayscale (colors--> grayscale). Now to add a nice blur to it we (Image -->Blur -->Motion blur) and you should find that your black surface has a nice "blemished" look to it. If you want to do anything more to your texture at this - feel free, but I will stick to the topic and get into making the texture. You can create a seamless texture by selecting by (Selection --> Create a seamless pattern). Almost there! Resize the image (Image -->resize) and make it a power of 2 (2,4,8,16,32,64,128,256,512,1024,2048) make make it SQUARE. None of this will work if the image isn't a square (128x128 or 256x256). Now save the image as a .pcx file (Zsoft paintbrush Ver 5). You can skip the next part if you like, as it only goes through the same thing, but about an actual image...

Creating a "picture" or detailed texture:

If you did the part above, then this is a peice of cake... All you have to do is get the image that you want, make it Square, and save it as a .pcx file (Zsoft Paintbrush Ver 5) and go onto the next part...

Importing into Unreal:

Load into Unreal. Where you see the texture bar, select "import" from the options down the bottom. In the window that is created, open the file that you have just created. You can name the "Texture Group" by placing any name you like in the "Group" box. When you have done this, click OK. You should now have a wonderful little texture that is either a blemished metal, or the picture that you saved. Now to save the "Texture Group", select "Save" from the options below the texture bar, and you will be asked to enter a name... Name the group whatever you want, and click save. Now you will be able to give other people the the file with all your cool textures... It will also come in handy if you are posting your map anywhere as the people will (I think) need the .utx file that you created to play the level.

Important Notes:

Make sure that the image you have created is in 256 colors, otherwise you will get a "bad something" message, and the program will hang... (I found this out the hard way...) If you want to add multiple textures into one group, then simply choose the particular group that you want to add into (from the normal texture bar options) and click import. It will default into the open group. Just make sure that you save the file before getting out of the editor...


BB Drac - Unreal Tournament UED2 guide Texture / Walls explained

Texture / Walls Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Walls, also known as polys, are sides of any brush.
A rectagular brush have a total of six sides/polys.

All sides can have its own texture and properties.

I would say that most of you know what this is so I will list
the flags you can set for each wall/poly.

Flag | Specific
Invisible | Removes the texture from view.
Masked | The color index 0 will be transparant if imported as masked.
Translucent | Players will be able to partly see through the texture.
Force View Zone | Do not know what this do.
Modulated | Works as Translucent but do not 'light' up as much.
Fake Backdrop | Used to link the texture with the skyzone info actor.
Two Sided | The wall/poly will have two sides.
U-Pan | Adds sideways movement to the texture.
V-Pan | Adds vertical movement to the texture.
High Shadow Detail | Surface will have better light/shadow detail.
Low Shadow Detail | Surface will have lower light/shadow detail.
No Smooth | Do not know what this do.
Special Poly | Do not know what this do.
Small Wavy | Adds a wavy movement to the texture.
Dirty Shadows | Do not know what this do.
Bright Corners | Corners of the texture will 'attract' more light.
Special Lit | Texture is only lit by lights with the bSpecialLit true.
No Bounds Reject | Do not know what this do.
Unlit | Texture is unaffected by lights and use its original color.
Portal | Wall works as a 'zoneportal'. Is check when adding ZonePortals.
Mirror | The wall reflect images, like a mirror.

Mirrored walls:
You can, by checking the mirror flag, create a wall that works as
a mirror.
Also check the "Unlit" flag as this wall is supposed to reflect light and
images, not be affected by it.
If you want to create shiny surfaces or walls that reflects images
you need to check the "Translucent" flag aswell.

You should avoid creating mirrored mirrors (walls that mirror each other)
to avoid drop in game speed.
The game engine only calculates a specific amount of mirrored images deep.
(I think it is 7 or 8).

 High and Low shadow detail:
By setting the flag for either High or Low shadow detail
you can adjust how "good" the wall will look regarding lighting.
The setting also affects game speed.
If you set both options you will produce a "UltraLowShadowDetail" which
is wall detail level lower than "LowShadowDetail".

Can be used to rais gamespeed in certain areas.

 U / V -Pan speed:
When setting U or V panning for your texture you can adjust the speed with a
zoneinfo actor.
Under the property 'ZoneLight' you have 'TexUPanSpeed' and 'TexVPanSpeed' that
adjust the panning speed of all panning textures inside that zone.

 Textures alignment:
When you open the properties for a wall/poly you can adjust the
flags.
If you want to adjust the size and direction of the texture on the wall/poly
you need to press the 'alignment' tab.

To move the texture (panning) you can press the button 1, 4, 16, 64
for either sideways or vertical. Hold down shift to move the opposite direction.

Four buttons 45, 90, Flip V and Flip H to rotate / change the direction of the
texture. Hold shift to rotate in the opposite direction.

To change the alignment you can do so by the four alignment buttons.
They will rotate the texture to align it with the option you select.

The last section scales the texture, either with one relative value or
individual Horizontal and Vertical values.

You can change the editor mode to texture pan or rotate.
When active, you select the texture, hold down the CTRL button and either the left
or right mouse button and move the texture as you like.

 Importing textures:
To import a texture you open the texture browser select file and 'Import'.
Then select the image you want to import.

This image must be either .bmp or .pcx format.
The size must be within 1 and 1024 but in the power of 2.
256x256 is maybe most used but 128x128, 64x64, 256x128 is perfecly legal.

The rendered size is however not more than 256x256 which means that any texture
larger than that is scaled which will give the texture a more 'blurred' look.

All textures in UT use a 256 color palette which means that if you import images
with more colors it will be converted without dithering.

When you have selected the texture you want to import you get a new window
with some information you need to enter.
Package - Enter what texture package you want to add the texture to.
Type 'MyLevel' to let the texture be saved along with the level.
Group - Enter which group you want the texture to belong too.
In most cases you probably would type 'Base'.
Name - This is the name of the texture itself.
Masked - Check this if you want color index 0 to be treated as transparent.
MipMaps - Creates a low resolution image of the original for antialiasing.
Should always be checked.

To save a texture package just select file and 'Save'.
The file will have the extension .utx and must be saved in the
'...\UnrealTournament\Texture\' folder.
If you use textures from custom made texture packages in your level you need
to include it with the level to allow others to play it.

 Animated textures:
To create animated textures you need to import each image with the name;
[NAME]_a00 to [NAME]_axx.
A four image animation would be named;
[NAME]_a00, [NAME]_a01, [NAME]_a02 and [NAME]_a03.

[NAME] can be anything you like.

When all images have been imported they are by default animated when used.

Just make sure you use the first image in the animation sequence.
This is because the texture will only animate from the image you used, to the
last.
A four image animation will animate 0, 1, 2, 3, 0, 1, 2, 3... if you
use the image 0.
If you use image 2 it will animate like this; 2, 3, 2, 3, 2, 3...

Still, there is a few properties you can adjust the animation with.
Press the right mouse-button on a texture, select properties and expand
'Animation'.

AnimNext - The next texture in the animation sequence, 'none' to
return to the first texture.
MaxFrameRate - Maximum animation speed, can be slower.
MinFrameRate - Minimum animation speed, can be faster.
PrimeCount - Animates the texture specific amount of times before rendered.
Used to prevent possible slowdowns when the animated texture comes in view.

The properties should also only be applied to the first image in the animation
sequence.
With the exception of 'AnimNext' which you might need to adjust to get the animation
you want.

As a last note, it is perfectly ok to use animated textures anywhere you use
regular textures, on walls, coronas, water, 2D skins and so on.


BB Drac - Unreal Tournament UED2 guide Texture list

Texture List

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

This is a complete list of all original UT textures and what
they contain.

 Note:
Some texture that does not belong to any specific group can't be
seen in the texture browser unless you check the checkbox for "All".
The texture set that has some of this, is marked (*).

Texture | Specific
Botpack | Effects, Weapon effects, Flare, Icons, Team symbols and Explosion effects
Unreall | Effects and Skins
Unreal Share | Effects, Explosion effects, Lightning effects and Smoke effects
AlfaFX | 3x effects
Ancient | Inca/Aztec style Wall, Floor, Ceiling and Decoration textures
ArenaTex | Few Greenish Metal textures
Belt fx | Few effects
BluffFX | One Blue Electric effect
Castle1 | Two textures, Masked Archway and Horizon
ChizraEFX | Three textures, Blood, Blue Torchlight and Water
City | Div. city related textures plus some logos and sky
Coret FX | Metal based textures, Lights and Glass
Creative | Creative logo
Credits | Credits, Logos and Effects
Crypt | Two textures, Masked Rusty Chain and Rusty Metal
Crypt2 | Gothic/Occult Stone/Wood textures, Masked Bars/Chains, and Decoration
Crypt_FX | Stone Wall textures and Colored Lights
CTF | Red and Blue logo based walls, Ancient to Future style plus Glass
DDayFX | Shore, Horizon, Masked Barbwire and crate texture
DecayedS | Heavy and Alien feel textures, Walls, Floors, Special looking lights and Decoration
Detail | A few very detailed Grey Textures
DMeffects | One Water Motion texture (Sewer opening?)
Egypt | A few Tan Stone textures, some with Decoration
EgyptPan | Egypt/Desert texture for skybox
Eol | Marble and Decorated Stone/Walls and One Moon texture
FireEng | A few Lava, Water, Effects and Torch Fire (*)
FlareFX | A few Blue Flares
FractalFX | Three Asphalt textures, Two Animated (Red/Blue) Lights and some div. textures
GenEarth | Alot of Stone and Earth textures
GenFluid | Lava, Sky and Water textures, none animated (*)
GenFX | Lensflares, Gradient, Palettes and Masked textures
GenIn | Crystals, Medieval Decoration, Glass, Cloth and Colorful Tiles
GenTerra | Detailed ground textures and a few Reallife Skybox Backgrounds
GenWarp | A few specially animated (Water and pan) and some "Ghost"/Warped textures
GreatFire | Fire and Torch Fire textures
GreatFire2 | Animated Bubble, Lighting, One Blue Torch Light and One Slime Water skin
Hubeffects | Water, Lava, Lightning effects, Torch Fire, Waterfall and a few other textures
Indus1 | Skybox, Stone, Blood and Effects
Indus2 | Skybox, Stone, Effects (Water/Lightning), (*)
Indus3 | Metal and Motion blur Wall, Skybox and Ground textures (*)
Indus4 | Animated Flare, Effects and a Star Sky texture
Indus5 | Animated Screens and Wood textures
Indus6 | Masked Glass, Skyzones, Stone and Wood textures
Indus7 | Animated and None Animated Screens
ISVFX | Lightning and Energy Effects
JWSky | Skyzone textures
LadrArrow | Animated Arrow
LadrStatic | Animated Static
LavaFX | Lava textures
Lian-X | Lava, Flowing Lava, Stone, Warning signs and Walls
Liquids | Water textures
Logo | UT logo and a Blue "Fire" texture
MenuGr | Logo, Logoflame
Metalmys | Metal walls and wood crate textures
Mine | Mine/Dungeon Walls, Floors, Ceiling, Lights and Masked textures
NaliCast | Fantasy/Ancient Castle (Stone and Wood), Windows, Walls and Decoration textures
NaliFX | Lightning Effects, Torch Fires, Water, Lava and Signs
NivenFX | Water and Lightning Effects (*)
Of1 | A Brick Wall and A Grey Panel Floor texture
Old FX | Decorated Walls and Door, Lightning Effects, Masked Chain and Harvest textures (*)
PhraelFX | A Waterfall and two Lantern textures
PlayrShp | Rough Metal Walls, Floors, Ceilings, Decoration, Doors and Lights
Queen | Science Fiction Alien based Walls, Floors, Ceilings, Decoration, Doors and Lights
RainFX | Concrete, Metal, Wood Walls and Decoration, Few Effects, Water and Wet Glass
Render | One Default Bubble Texture
RotatingU | Unreal Logo
ShaneChurch | Stone and Wood Floors/Walls, Painted Glass, Detailed textures and two Moons
ShaneDay | Skybox textures, Mountains and Sun flare
ShaneSky | Blood colored Skybox textures, four Moons and Sun Flare
Skaarj | Alien/Outofthisworld Walls, Floors, Ceilings, Decoration, Doors and Lights
SkyBox | Skybox textures, Mountains and a Moon (*)
SkyCity | Fantasy/Ancient (Jade Green) Walls, Floors, Ceilings, Decoration and Col Windows
Slums | Brick/Concrete/Metal Walls, Graffiti, Signs and Lights
SpaceFX | Effects, Water, Masked, Flares and Skybox textures
Starship | Alien look Walls, Floors, Ceiling, Panels, Signs and Decoration
TCrystal | Effects, Blood, Lava and Water
Terranius | Lightning Effect and Smoke (*)
TrenchesFX | Brick and Stone walls, Fan and Light
UT | Div Stone, Wood and Metal Walls, Decoratio
UT ArtFX | Effects and "Art" textures
UTbase1 | A few Metal Walls and Pillar
UTcrypt | Stone walls and Colored Lights
UTtech1 | Dark Stone/Metal Wall, Floor, Ceiling, Crate, Light and a Snow textures
UTtech2 | Smooth Stone Wall, Floor, Ceiling, Light and Crate textures
UTtech3 | Lights, Decoration, Signs and a "Laser grid" Effect
XbpFX | Div. Wall, Skybox, Moon, Earth, Space Phenomena, Warning textures w/numbers
XFX | Water, Slime, Lightning Effects and Flares (*)
Xtortion | Smooth Grey Wall, Decoration and Lights
BossSkins | Skins
Commandoskins | Skins
DacomaFem | Skins
DacomaSkins | Skins
Faces | Player Faces
Fcommandoskins | Skins
Female1skins | Skins
Female2skins | Skins
GothFem | Skins
GothSkins | Skins
LadderFonts | Fonts
Male1Skins | Skins
Male2Skins | Skins
Male3Skins | Skins
Palettes | Palettes
Scripted | Fonts
SGirlSkins | Skins
SkTrooperSkin | Skins
Soldierskin | Skins
UWindowFonts | Fonts


COOL CUSTOM TEXTURE EFFECTS

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

I'm just gonna show you how to take a base existing texture and apply texture effects to it like ripples.

NOW YOU KNOW............

  1. First off, in the texture browser hit File > New... and in the dialog box that opens enter the following :-

    It helps to know the width x height of the original base texture that you are using. In this case the dimensions of GenIn > Deco > Rotwood2 texture is 64x128 - this is the texture that I want to change.

  2. It defaults to an empty texture like this :-

    You need to assign a source texture under water paint (in this case).

  3. Expand water paint and select the desired texture (Rotwood from GenIn.utx in my case) and hit the use button in the source texture field.

  4. Now hold down the left mouse button and drag it on the image previewed on the left in the desired way that you want the effects to appear. Paint on the picture actually. Now you should have something like this :-

  5. Ok as you would have noticed its way too big. Play around with the settings till you get the desired effects. Mine were like this :-

    Notice the difference between this one and the previous one. Now it looks a little more realistic.

  6. Save it and you are ready to go.


MULTISKINS

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

Small tutorial on how to make use of multi-skins in you level. It helps you assign different skins to existing decorations to make them look different and how multi-skins work.

MAKING A BOT (SOLDIER) DECORATION

Lets see how to put a fully skinned bot into your level - you cant do that normally so here's how you do it:

  • Loacate the following selected item and place it in your level:-

    /me love putting images in tutorials so see me ..... in court where else :p.

  • Hmmm...... hey you ugly dude u look like someone I know:-

    A horse that is ;). We got to change that pronto.

  • Double click the TMale1Bot and go to its properties. Now expand display and you'll find the things you need to change there :-

    /Holy Toledo a sensational discovery has been made :p. More attempts at pathetic humor ignore this part, bangs head against wall to make himself stop :).

  • Now fire up the texture browser and load up the skin package that you want to use. eg:commandoskins.utx. All the textures will be conveniently named for you. All you have to do is press the use button against the selected multi-skin part. e.g.: cmdo1 must be put in the MultiSkins Slot [0], cmdo2 in MultiSkins Slot [1]. MultiSkins do exactly that assigns skins to multiple areas of a mesh. Slot [0] for one part Slot [1] for the next part and so on. Ok now all you got to do is set the MULTISKINS (note that I mention specifically multiskins and not SKIN).

  • The coolest step yet!!!!!!!!. Now do that one two three thingy and see what you get.

    /me refuses to stop proving a point :). Slot [0] assigns a skin in this case to the hands and leaves the other parts unskinned.

  • Ok the full skinned model is here to rock:-

    "What the hell u starin' at, if looks could kill you'd be dead by now"
    (sheepish grin :) the skin is actually from one of my all time fav UT mods AgentX. Click here to go to their official site (defunct now I think).

GENERAL NOTES

  • See the list below:-

    Every model needs to be given like a different set of multi skins. If you try to like apply the male commandos skins on the TFemale1Bot you'll naturally get weird stuff since the skin doesn't account for the ......... um ......... puppies ;). If you want a skinned Xan in the level you need to use the TBossBot, the commandos skin the TMale1Bot and the soldier skins the TMale2Bot and so on.

  • The bots>human bot refers to the Unreal1 multi-player player models and uses only one skin - unlike the UT models.

  • On playing the level the above mentioned stuff will attack you with the intent to kill (naturally :). If what you are actually looking for is a 'dead as a door knob" decoration style skinned bot you need to use the carcass of that specific bot which are conveniently named just like the animated AI bots.

    Hmmm.... what u guys doing paragliding :p ?.

  • You'll find nearly all the skins for the Unreal 1 player models and all the skins of all the decorations (UT and unreal 1) under the Unreall.utx>skins package.

CHANGING DEFAULT DECORATION SKINS

A brief mention of this will do. All decorations except for the above mentioned carcass use only one skin. Besides this in the multi-skins (most of the time :) they make use of only Slot [1]. In the above paragliding [?:)] picture the slot that uses the soldierskins.blkt2 texture. So if you wanted to change the skin of the default barrel provided under decorations you just select a nice board texture and put it in multi-skin slot [0] or for the monk statue use slot [1].

This concludes another tutorial. If you have any doubts email me here : cool_machismo@yahoo.com. Peace To All :).


deCyber Build Section

Textures

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Downloadable files : Texturing.zip (contains 2 graphics files for importing practice).

Contents

1) Picture Preparation
2) Importing your textures
3) Screenshots

Introduction

Importing your own textures can be very rewarding. It can customize your maps in endless ways.

Picture Preparation
Before you even open UnrealED, make the following preparations to make sure you can use your textures. I've enclosed two picture files for you to experiment with. One is a standard jpeg file for you to convert and try, and the other is a prepared pcx file that should be ready to import.

1) Make sure your picture is in an 8-bit pcx format (like the example file). If your picture is in jpeg or bmp format then use an application like paintshop or photosuite to convert it. Some applications make your textures go grainy when converting them so make sure you use the right package.

2) Ideally your pcx picture should be in the following size:
64x64, 128x128, 256x256 or 512x512.

3) It may also be helpful to give the pcx file a name that you're pretty sure won't be in any of the other texture packs. I'm not sure, but I think the editor can get confused as to where it should pick the texture from otherwise.
If your picture has not been set according to those criteria, you won't be able to import it!

Importing your textures

1) Open up UnrealED.

2) Open up the "TextureBrowser" from the icon on the toolbar that looks a small painting.

3) Click on "File" and then "Import"

4) Fill out the info in the new window as in the example but make the texture whatever you want to call it.
Always keep the package name as "MyLevel". When you import your textures to "MyLevel" they will always be integrated into your map and you won't need to include a separate texture file in with your zip.

5) Once you've imported it, you should see your new texture file in the window.

6) Make sure that each of your imported textures is used in the map somewhere it will not be kept by the editor!

Screenshots

When making your map for UT, its always nice to have a screenshot for your map so that the UT menu can give people a hint as to what your map will be like.

1) Use the method above to import your screenshot as a texture.
Make sure it is 256 x 256 and as usual it must be 8-bit.
It must also be called "Screenshot" (but without the quotes obviously)

2) Once you've imported it. Right click somewhere in your grid and choose "LevelProperties"

3) Open out the "LevelInfo" section and make sure your Screenshot is selected in the browser.

4) In the section called "Screenshot" in the Level Info click on use and you're finished. Check out the menu in UT to see if it shows up.

EZkeel
(Simon West-Bulford)


Unreal Tournament Texture List

by: Jason Morgan
jason.w.morgan@talk21.com

This list is here as a rough guide to where to find certain textures, as much for me as anyone else, as there are so many of them in odd, out of the way places. It doesn’t list every texture pack, only those that seem to me to be useful. Some of them are just obvious, and others less so..

Ancient - Ancient Greek/Roman/Egyptian Textures. Lots of walls, floors, pillars.
ArenaTex - Textures from the arena at the end of the intro. Small collection of futuristic textures.
Castle1 - Two texture from DM-Barricade. Sky and arch.
ChizraEFX - Animated blood and water textures and a blue flame.
City - Textures from the intro. Many futuristic-style city textures, as well as sidewalks, rubble and masked metal grid floors. A number of ‘Caution’ textures, and walls of skyscrapers.
CoretFX - A number of futuristic space station/under water textures. Textured non-slip floors, matching walls, glass.
Crypt - Very old fantasy style - A chain texture and a metal floor.
Crypt_FX - Very old fantasy style - Painted glass textures. Good for lights or windows. Three wall textures.
Crypt2 - Lots of very old fantasy style textures. Matches with the above two. Many wood based walls, pillars. Wood textures. Different styles of stone walls. Three ceilings and lots of tile floors.
DDayFX - Beach and water textures from AS-Overlord. One animated waves and water. Skylines.
DecayedS - Decayed, dirty looking space ship textures. Many floors and ceilings. More than thirty pillars. Many different styles of wall.
Detail - A selection of greyish textures. Could be used for stone.
Egypt - Ancient Egyptian textures. Hieroglyphics. Sandy coloured walls and floors.
EgyptPan - Ancient Egyptian textures. Hieroglyphics. Egyptian skylines.
EOL - Selection of textures. Modern wooden and tile floor textures. Evil undead style walls.
FireEng - Animated fire, lava and water textures
GenEarth - Earth and rock textures.
GenFluid - Animated water, lava and slime. Skies.
GenFx - An odd selection of textures. Some lights and water plants as well as some strange gradients.
GenIn - Lots of different textures. Crystal, blue and red carpets, stained glass, glass, wood textures and some very 3D looking tiled roofs.
GenTerra - Lots of grassy soil textures.
GreatFire - Animated fire textures
Indus1, 2, 3, 4 - Odd selections of textures. Seems Fairly random.
Indus5 - Has some good wood textures
Indus6 - Some pirate ship textures, and some tile floors.
Indus7 - Lots of computer screens.
LavaFX - More animated lava textures.
Lian-X - An animated lava texture, dripping lava texture and some cobbled floors.
Liquids - Water and slime textures.
MetalMys - Lots of wrought iron/metal textures
Mine - Lots of mine/futuristic mine textures. Iron walls, stone walls. Metal floors.
NaliCast - lots of Castle textures.
ShaneChursh - Church textures. Stained glass, arches.
Skaarj - Dirty, ‘evil’ futuristic spaceship textures.
Slums - Slum textures. Brick walls, concrete, dirty metal.
Starship - Lots of different styles of starship textures, in blue and brown, as well as other universal starship textures.
TrenchesFx - Concrete textures.
Xtortion - Futuristic textures.


BB Drac - Unreal Tournament UED2 guide Level Info

Level Info

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Level properties is used to give your level some default values.
In reality level properties work like the zoneinfo but affect the
entire level instead of a single zone.
Zoneinfo on the other hand overrides values used in level properties
making you able to better control the level environment.
(Read the zone tutorial for more info. on zone specific properties).

Level properties is also used to give the level default music and
game specific information.

You can open the level properties by pressing "F6" or select
"View" and "Level Properties" from the menu.

This list show you what level related info. you can change.

Level Property | Specific
+Audio |
CdTrack | Play a specified track from a music CD (255=none).
Song | Play a specified song (.umx file found in the music browser).
+LevelInfo |
Author | Name of the level creator.
Brightness | Adds a default brightness to the level.
DefaultGameType | What game type the level is, DM/CTF/DOM or AS.
IdealPlayerCount | Here you type the recommended amount of players.
Screenshot | This is the screenshot shown when selecting level in UT.
Title | Simply the name of the level.

A Screenshot:
There is a few things concerning screenshots.
The size of the image must be 256x256.
If you want it to be saved along with the level you must import it to
the texture package "MyLevel".

To create a screenshot of your level you should enter it as a spectator.
(Preferbly remove the info hud).
When you find what you want a screenshot of, press "F9".
The file is stored under the "...UT\System\" folder, "shotXXXX.bmp".
Open this file in any picture editor, resize and cut it to 256x256.
This image you then import from the texture browser.
(UED2 is fully capable of importing bmp pictures so don't worry).
Under "Package" you type "MyLevel".
Let the "Group" be "Base", and type "Screenshot" in "Name".
Press "Ok".
This texture will now be saved along with your level.

 Changing the game type:
UT is able to load the level in correct game type if the filename of the
map correspond with the correct game type.
DM-[mapname].unr, CTF-[mapname].unr, DOM-[mapname].unr or AS-[mapname].unr

But, unless you do this UT will treat the map as DM and to change that
you need to set the correct "DefaultGameType" in Level Properties.
The game types are found in the actor browser under "Info", "GameInfo" and
"TournamentGameInfo".
For DM you have "DeathMatchPlus" and for Last Man Standing, which is a
type of DM you have "LastManStanding".
You will also find the game types for CTF, Assault and Domination which is
"CTFGame", "Assault" and "Domination" located under "TeamGamePlus".

There is other game types you can use, like intro and training but they
aren't explained here.


Fire

    By:BEG

    ASSUMPTIONS:

    This tutorial assumes that you know your way around the basic interface of Unrealed.

    TUTORIAL:

    Ok after you have UnrealEd loaded you can load up the texture sets that you will need, over in the Browser pane you should see a group of buttons at the bottom of the screen, press Load and load up the Ancient and GreatFire packs.

    Now we want to make a simple room, right click on the cube brush and select "Cube Properties..." this will pop up a box where you enter the width, height etc. Change the Height, Width, and Breadth values to 512, hit build this will resize the cube to the new values, then hit close.

    Ok now go to your Browser pane and select Ancient from the dropdown menu and select a wall texture you want to use, hit subtract and we now have our room. You can now change the floor and ceiling textures if you want.

    Now right click on the Cylinder brush and go to "Cylinder Properties..." Change the height to something like 128 and both Inner/Outer Radius to 64, hit build. And close the popup window.

    Move the Cylinder so it is in the center of your level and is flat on the floor, select a new texture for the Cylinder if you want and Add it to the world.

    Right click on the Sheet button on your toolbar menu and select "Sheet Properties..." This is what the fire will be placed on. Set the properties to Y-wall, U value of 64 and V to 128. Build the sheet and close the popup window.

    Move your sheet so it is in the center and sitting on top of your Cylinder that you added into the world. Select a fire effect to apply onto the sheet, such as 'ANCPURP'.

    Click on Add Special brush in your toolbar, this will popup a new window, on the drop down menu select masked texture, then change the visibility options to 2-sided, and make sure Transparent is checked in Effects. Click add special and then close. The fire texture may be tiled but don't worry about it at this point.

    Click on the rotate button on the toolbar and rotate your red sheet builder so it is at a 90 degree angle from the one you just created, and repeat step 8.

    Now your fire texture is probably tiled so highlight them in your perspective window and enter their surface properties, under scale make Simple Scaling 2 and hit apply, the textures should be sized correctly now.

    Place lights, now place a light or multiple lights and tweak them until you are satisfied with the lighting.

    Note: Don't place lights directly above your fire effect they will drown out the texture and will make the fire like ugly.

    Add a PlayerStart and rebuild your level.


Wolf's Tutorial Special Effects 1

Wolf's Tutorials: Fire, Smoke & Fog

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Fire, Smoke & Fog

In this tutorial we are going to cover such things as Fog, Fire, and Smoke. Some of the really cool special effects that set Unreal apart from other FPS games.

Ready . . . Aim . . . Fire!

Everyone wants fire in their map at some point. Here is how it's done. There are actually several ways to make and several types of fire. We are going to concentrate on the two easiest to get you started. The first is a TorchFlame and the second is a simple masked texture fire.

TorchFlame

Too easy...gimme something harder..oh, alright..here's a simple torch: Make a standard 256 x 512 x 512 room. Pick some pretty textures and subtract the room. Now, we need somewhere to place the flame, so build a 64 x 64 x 64 box in the room. Texture it as you see fit. In the Browser go to Classes, Light and select TorchFlame. You are probably way ahead of me, but right click the top of the box we made and Add a TorchFlame actor. Center it on top of the box. Rebuild. You can adjust the light properties of the TorchFlame Actor just like any other light.

Since the 220 build, the TorchFlames are much bigger than they used to be. You can adjust the size of the TorchFlame by right clicking it to bring up it's properties and under Display setting the DrawScale. I usually use .5 myself. One is normal size, .5 half, etc...
Note: This does not affect the light out put, just the size of the flames.

Sheet Flames

You can make other types of fire using masked sheets. Load the GreatFire.utx texture pack and look at some of the different flames. We are going to use these textures.

First let's build something for the flame to sit on. In the same room make a square 32 x 128 x 128. Texture it and add it to the world. Now select a nice fire texture from GreatFire.utx like AncFlame1. Open the Sheet properties, click X-Wall and make it 128 x 128. Position the sheet on top of and in the center of the little box we just added. Click Add Special and go to Masked Wall. Click 2-sided! Now add the The special brush, and you should have a flame atop your little dais. Click the flame and open the texture properties and set Unlit. Add a PlayerStart and then rebuild. Run the map. The flame looks ok on there but when you look at it from the side, you can tell it's a flat sheet! Take your red brush and rotate it 90 degrees so it forms an X with the first sheet and add another flame sheet like the first one (making sure to make it Unlit).

Now rebuild and run it again. Ah...better.

Note: To me this type of making a flame looks much less real than just adding a TorchFlame, plus it doesn't give off any light of it's own. I usually only use sheet fire in recesses in the wall where they are only visible from one side, or in other "special" situations.

Let's build another sheet flame that looks better. Build a niche in one wall 128 x 128 x 32. Align it in the center of the wall, a few units off the floor and subtract it.

Now select a fire texture like AncHot. Add a sheet (just like we did before) in the center of the niche.

Make sure the texture on the flame sheet is unlit. now add alight in front of the flame and give it a reddish color.

We can also add a grate in front of the fire. load the NailCast.utx textures. Go to Mask and select one that 128 x 128. using the same sheet brush we just added the last flame with, move it to the edge of the niche where we added the flame. Leave all the properties the same and Add Special. You should now have a masked grate in front of the flame.

Note: This grate will not block anything (gunfire, players, bots...). If you wanted to block them you could add an Invisible Collision Hull. To do that select the cube brush and make it 126 x 126 x 1. Yes, ONE unit thick. Right click on the GRID and change the grid setting to 2 units. Now move the grate sheet back into the niche one one "snap" or two units. Place the new cube brush at the edge of the niche, but not touching it. Note: We made the "grate" smaller than the opening because if the masked brush (the grate in this case) touches the subtracted wall we will get a HOM or Hall-Of-Mirrors effect there. If you don't know what I am talking about then make the grate the same size as the opening, add it and then run the map.

Now, under Add Special, choose Invisible Collusion Hull from the drop down menu and add the brush. It should be invisible in the 3d view. If you click the little joystick icon it will appear.

The thing I don't like about collision hulls is that it adds an extra step. If you made the grate out of the 1 unit thick brush you would get the same results. Delete the grate brush and the collision hull. Now move the brush we used for the collision hull where the grate sheet used to me. Select the grate texture and Add Special Masked Wall. Now rebuild the map and run it. Works good, huh? And we eliminated a whole step (adding the grate sheet).

Note: The whole reason you have to either add collision hulls or make the one unit thick brush is because a sheet will NEVER block actors, no matter how you set it. There is a lot of confusion on this issue, but the fact is a SHEET WILL NEVER BLOCK ACTORS!

Smoke

Where there's fire there's smoke...or there should be. To are (as in a lot of cases with UnrealEd) several ways to make smoke. One way it to find a cool smoke texture and add a sheet just as we did with the flames. Another way would be to use the Smoke special effects from the classes menu. Since you make the smoke sheet exactly as you did the flame sheet, I'll show you the Special Effect method.

We'll keep using the same map we have been working on. Let's make a new room and then connect it to the first room. Make a small hallway first, let's say 256 x 256 x 256. Place it in the middle of one of the bare walls, against the floor then subtract it and texture it. Now make your brush 512 x 512 x 512 and add a room on the other side of the hall. Your map should look something like this now.

We are going to add another TorchFlame in this new room and then add some smoke over the TorchFlame. First go back to the first room and click on the block the TorchFlame is sitting on to highlight it. Now right-click and Copy Polygons To Brush. Click the grid to unhighlight the brush and move the red brush to the center of the new room on the floor, and add it.
Add a TorchFlame to the block as we did before. Remember to resize it so it fits correctly (or you can copy the first torch flame by highlighting and clicking CTRL-W and moving the new TorchFlame into place). Now open the browser, go to Classes, and then Effects. See the two classes titled SmokeHose and SmokeHoseDest? We are going to use those.
The first one, SmokeHose, is where the smoke will generate, and the second SmokeHoseDest is where it is going to. We need to add the SmokeHose just over the flame and the SmokeHoseDest near the ceiling. Go ahead and do that now.

Rebuild and run the map. You should see a little trail of smoke rising up from the flame to the ceiling. Easy, huh? Now, I wouldn't use this on every flame in your level, as I am sure lots of these will slow down the map, but you can use it occasionally to get the desired effect.
You can adjust various settings in the SmokeHose Properties to change things like the size of the smoke puffs, the speed they rise, the variation of the individual puffs, etc . . . Experiment with the settings to see what kind of things you can do with it.

Smoke Generator

Another way to make smoke is using the SmokeGenerator class under Effects. The only thing about smoke geneartors is that they have to be triggered to work.
Okay, go to the SmokeHose & Dest we added and delete them. Instead, put a SmokeGenerator above the TorchFlame. See that nice puff of smoke? That is where the smoke will enimate from. Clcik it and bring up it's properties. We only need to set a couple things to get it working. One is give it a tag under Events. I used "Smoke1" to keep it simple. Under Smoke Generator, set bRepeating to true. Now add a trigger right by your player start. Set it's event to "Smoke1" Rebuild and run the map.

Tips: You can play with settings under SmokeGeneartor heading like BasePuffSize, RisingVelocity, etc... to get various effects. I usually use SmokeGenerators for regular, rising smoke and normal fire smoke, and use SmokeHose for "special" situations.

Fog

One of the most frequently asked questions by a new UnrealEd users is "How do I make fog?" This tutorial will show you how, and give you some tips on how to do it so it looks good.

Like so many things in UnrealEd, fog is made by using a zone. Basically all you need is a zone, a ZoneInfo, and a light. Light is the key. The ZoneInfo tells the game engine "here, there be fog..." and the light "shows" you that fog.

Okay, start by making a small hallway coming of the last room we made. make it 128 x 128 x 256. Now make the brush 128 x 128 x 512 and connect it to the last hallway at a 90 degree angle, making an "L."

Now make a room 512 sq. Add it at the end of the hallway like this:

Now we need to "zone off" the fog area. To do that make a sheet brush big enough to cover the hallway opening (in this case 128 x 128) and place it in the hall. Place it like below:

Now go to Add Special Brush and from the drop down menu select Zone Portal and then Add Special Brush. Now rebuild and you will see that the light from the last room does cross the Zone Portal normally.
The Zone Portal is invisible and cannot block actors because it is a sheet. Note: If you change the 3D view to Zone/Portal View (under Mode) you should see that the area on one of side of the ZonePortal is one color and the area on the other side a different color. If this is NOT true, then you have not placed the ZonePortal properly. Delete it and try again.
Tip: The Zone/Portal View is an excellent way to check your zones integrity. you can check ALL zones this way.

Now we have to make the new zone a fog zone. Go to Classes, Info, and add a ZoneInfo somewhere in the last room we made (512 sq). If you expanded the ZoneInfo you didn't see a FogZone did you? There isn't one. Just use the generic ZoneInfo and we will set it to a FogZone.
Highlight the ZoneInfo and open it's properties. Expand ZoneInfo and the second field down should be bFogZone. Set this to, you guessed it, true. Add a light in the center of the room. Open the LightProperties and expand Lighting. See the three "Volume" settings at the bottom (VolumeBrightness, VolumeFog, VolumeRadius)? These are the setting that make the fog appear. Try setting them all to 32 except VolumeBrightness--leave it at 64. Rebuild and run the map.

You should now have fog in the last room. Try changing the Volume settings under the light Properties and see how it changes the fog.

Note: The reason we built our hallway/Room like we did and place the ZonePortal where we did is because fog is NOT visible from zone to zone. If you have a straight hallway that leads into a fog zone the fog will not be visible until you enter the fog zone, making it suddenly "appear" as you cross the ZonePortal. So try to make your fog zone in an area that is not visible from the previous zone.

More Special Effects will be covered in Part Two of the Special Effects Tutorial.

Using what you have learned

Play around with these effects and have fun. Try different things and see what looks good and what does and doesn't work. As always, if you have any questions e-mail me.

-Wolf

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


BB Drac - Unreal Tournament UED2 guide Light, open flame

Open Flame

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Create a room (256x256x256) and subtract it.
Screenshot

Create a small structure 64 height and 32x32.
Place this in the center of the floor and add it to the world.
Screenshot

To add the flame itself we need to use the sheet builder.
Create a sheet with the 64 height and 32 width and place it on top
of the middle structure.
Load the "GreateFire.utx" texture set and select "ancflame2".
Add the sheet using "Add special brush".

Select Regular Brush as Prefab and then check Masked, Transparent and 2-sided.
(If you are unlucky your brush will be upside down or sideways. If so, use the
surface properties to rotate it correct and maybe pan it a bit.)
In the surface properties check the flag "Unlit".

Now you select the newly created brush (in one of the 2D views) and
then select "Polygons" and "To brush".
Rotate this new brush 90 degree and add it the same way you added the first.

(If you have >v4.32 of UT installed you are able to do this sheet-building a bit easier.
Create a "volumetric" brush with the properties 64x16 and "NumSheets" 2.
Select the correct flame texture, place the brush ontop of the middle construction
and press the "Add special brush" button.
Select Regular Brush as Prefab and then check Masked, Transparent and 2-sided.
In the surface properties check the flag "Unlit".)

Screenshot

Add a light (press the right mouse button and select "Add light here") in the middle of the
flame.
Screenshot

Open the properties for the light and adjust the following values.
LightColor, LightBrightness: 128
Lighting, LightRadius: 32
Lighting, LightEffect: LE_TorchWaver

When that is done simply rebuild the lightning and enjoy.
Screenshot


Creating Fire

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: tyleraperry@juno.com

Date: Monday, December 21, 2000

Download: tut_fire.zip

Forward:

One boring day, one of my friends called me with a question about how to create fire in UnrealEd. Seeing that I had been teaching him how to use UnrealEd since he had it, I decided why not? So with that I taught him how to make fire, than, it occurred to me that this could be useful for the Unreal/UT community so I wrote this.

Abstract:

This tutorial will go over how to create fire in a level. This tutorial will not teach you how to create lens flares, or add sound, or lighting, to learn those, read my other tutorials. (Some may not be out).

Assumptions:

As always, I assume you know the basics of the editor.

Tutorial:

Introduction:

Flames and fire can add a great deal to your map, and can give it a wonderful atmosphere along with beautiful looks if placed correctly and created correctly. If done correctly, it won’t kill system resources.

Creating the Flame:

Create a room 512x512x512. Now, create a cylinder that is 64x32x16 and add it to the bottom of your box, then texture it. Your room should look like this:

Good, that was the easy part, let’s add the flame now. Click on the Build Volumetric Brush, and position it like this:

Load the texture set NaliFX.utx and select the texture Torches2 (128x128). After you have done that, click Add Special… Select Masked Decoration and make sure that 2-sided, transparent, masked, and non-solid are checked. Your Add Special should look like this:

Add the texture to your room. You may find that your texture is off centered, to fix that just align your texture the way you like them.

Select all of your fire textures and bring up the surface properties, then select the Flags tab and check Unlit and rebuild. Your flame should look like this:

Finished Flame Geometry.

Making the Flame Give off Light:

Now that you have the flame, there is one more major thing to do. Make the flame glow. Let’s do that.

Add a light in the direct center of your flame like this:

Flame Light Positioning.

Now, all there is left is to adjust the color of the light to something that suits you. Make sure you add torchwavy to the lighting effects for more realistic looking flames.

Adding More:

There is much more you can do to your flame, adding a lens flare, or some ambient sound would be a great idea. You will have to learn these in a different tutorial though.

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


Fog

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    Forward:

    Well, I just added some fog into a level that I am working on, so I had best make a tutorial that delves into fog, and how it is used in UnrealED.

    Abstract:

    I will explain the basics of fog and how to use it, as well as explain colored fog.

    Assumptions:

    I assume that you know how to create lights, as well as a basic room (at least).

    Tutorial:

    Introduction:

    Fog adds a feeling of being there, and that's what we wnat from our levels ins't it?

    Setting the scene:

    Before we get into fog, we must allow our editor to draw the fog. When you have selected a room for the fog to go, and go into the texture bar, but select "classes" now go into Classes>Info>Zoneinfo . Now add a "Zoneinfo" into your level. It doesn't matter where you place it, as long as it is in the same zone (don't place it underwater, if you want the fog just above the water level for example) as where you want the fog to go. Now open up the advanced properties, and then the zoneinfo tab. Change the "bFogZone" to TRUE, and close the advanced properties.

    The light settings:

    Well the hard part is out of the way, so now it's a simple amtter of placing the lights where you want them, and editing their settings like this...
    The "Volume Brightness" setting will determine how bright the light is inside the volume of it's area. The "Volume Fog" setting will determine how "thick" the fog is. The "Volume Radius" setting will determine how large the area is that the light and fog effect. It is possible to play with color settings as well, to create colored fog. In the example show here, I have created purple fog (No not a "Purple Haze" :)...).

    A Little Warning:

    Fog !!SLOWS!! down pc's, and it should really be used sparingly. Creating a Huge outdoor setting, then filling it with fog might sound cool, but unfortunatley, it would be unplayable on everything but NASA!
    If you have multiple zones, you will find that fog cannot be seen from one zone to another, so if you want multiple zones, then make sure you place a "Zoneinfo" in each zone where you want the fog, and set it to the above configuration.


BB Drac - Unreal Tournament UED2 guide Zone, Fog

Fog

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

In this fog tutorial we will simply look at how fog looks and how
the engine treat zones.

First start by creating a 256x256x256 sized room.
Create another room, also 256x256x256. Place this one 128 units to the right
of the first room.
Now add a 128x128x128 sized room and make it connect the two rooms.
Add texture and lights.

Screenshot

When that is done create a sheet 128x128 with AX_Xaxis.
Place it in the middle of our passage add press the "Add Special Brush" button.
Select "Zone Portal" and let the rest be. Press "Ok".

Screenshot

Now open the actor browser. Expand "Info" and select "ZoneInfo".
Add this "ZoneInfo" inside the room to the right.

Screenshot

Now to the creating of the fog itself.

You can do this by either using true fog or fake fog.

True fog looks real good and you can adjust thickness, covered area and color.
On the other hand true fog is very ressource demanding and can slow a level
down drasticly.

Fake fog actually only adjust the screen brightness and color fade to give
the illusion of fog. It has no depth whatsoever but demand no extra processing.

 True fog:
In the properties window for the zoneinfo actor you need to adjust a property.
Under "ZoneInfo" you have "bFogZone". You must set it to true.

True fog comes from light sources and we have three properties that we can adjust.
Open the properties window for the light in the same room we have the zoneinfo actor.
Adjust the following values:
Lighting, VolumeBrightness: 8
Lighting, VolumeFog: 128
Lighting, VolumeRadius: 24

If you want to change the color of this fog/haze, just change the color
of the light.

Note that the light have two radius values. One for the light itself and one
for the fog (LightRadius and VolumeRadius).

 Fake fog:
Open the properties for the zoneinfo actor and adjust the following values under "ZoneLight"
ViewFlash X : -0.5
ViewFlash Y : -0.5
ViewFlash Z : -0.5
ViewFog X : 0.5
ViewFog Y : 0.5
ViewFog Z : 0.5

Add a playerstart in the first room, rebuild and test it.

You can see that you are unable to see the fog, unless you
actually are inside the zone (this goes for any type).

 Seeing fog, cross zoned:
You are able to make true fog appear in more than the zone you created it in.

First you should understand that fog is the same as 'Volumetric' light and
need the "bFogZone" set true to be rendered.
This means that all zones that have this property false will never render/show
volumetric light (fog).

By setting "bFogZone" in all zones that players should be able to see volumetric
light, in or from, will allow fog to be seen across zones.

This also works perfectly ok with a skyzone.

 Rendering true fog:
I do not know if this is standard, but for some people UT set by default
that voulmetric light (fog) should not be rendered.

To fix this open the advanced properties, expand "Rendering" and make sure
that for each render device (Glide, Direct3D...) have "VolumetricLight" set
True.


FOG fx

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

Just shows you how to make fog and implement fog in your level. This one shows you how to set volumetric lighting and apply fog effects to a level. You need to set some different setting in UT to get fog to show up.

IMPLEMENTATION

  • Zone The Area :- The first thing you need to do is to zone off the area completely where you want the fog to appear. Even if its a huge area try working in a zoned off area - its just plain better for the frame rates. Only don't use huge zone sheets that's as bad for the frame rates as the above.

  • Zone Info Actor :- After the area is completely zoned off place a plain "zone info" actor in the level - from actor > info > zone info (without expanding it). Now all you need to set is a single property like this:-

bFogZone to true is all you need to set here.

  • Fog Color:- If all you want is white looking natural fog skip this step. I wanted to simulate a dust storm - so I needed to set the fog color to a brownish hue. SET THE VALUE's UNDER LIGHT > LIGHT COLOR.

Fog Color sets the fog color (duh ........... its me Einstein again ;) and fog distance the viewable distance that the fog covers.
NOTE: ALSO SET THE VALUE's UNDER LIGHT > LIGHT COLOR

  • FOG Emitting Lights :- To make fog appear in the level it is the light actor that needs to be used to cast fog as well as light. First ensure that you turn on radii view - in any of the views right click near the joystick and under the actors menu choose radii view. Now place the lights in your level that you want to cast fog and set the following properties under lighting:-

    For fog emitting lights the last three entries under lighting are the ones that we are concerned with:-

    • Volume Brightness - This has a lot to do with how white (if the fog is white in color that is) in degrees the fog will be.

    • Volume Fog - Thickness of the fog - use 128/127 for medium. 255 means the players wont be able to see anything unless they are upon it. The volume is the biggest frame rate reducer - if you want to push frames up set to a low amount.

    • Volume Radius - The area that the fog will cover. This works just like the light radius. The radius of the light is depicted by a red circle (controlled by Light Radius) and the radius of the fog by a pink circle (controlled by volume radius). Like this:-

  • Rebuild :- Rebuild time. Now just rebuild and play the level. You should see the fog now.

  • Volumetric Lighting :- If you are running the editor in software mode you should be able to see the fog in the level. If you are running in D3D fog does not show up by default. Now in UT hit the console (~) and type preferences without the quotes and hit it. Now when the preferences dialog box opens set volumetric lighting to true. You can do the same with UnrealEd2 itself from the command bar or going to the view menu> advanced options. Set it here :-

  • "May The FOG Be With You" :- Fog slows the level down so watch it buddy.

Email me here with questions or comments about this tutorial or my site :- cool_machismo@yahoo.com


Water

    By: Isolation

    Creating a Pool

    Lets begin with a simple room already done. Add in a PlayerStart entity (Classes -> Navigation Point -> PlayerStart) somewhere inside the room. Now with your Brush Maker mark where you want the pool to be. Make it about 400x175 with 200 units of height. Put it on the floor of your map (top of the marker hitting the floor), then hit the Subtract from world button and viola you have your pool (with no water ofcourse).

    Adding Water

    First lets load the liquid texture set genfluid.utx* is fine, this will be needed later. Now with that done hit the Build a Sheet button (button with the gray diamond) and your red marker should become a thin line, right click the Build Sheet button and go to Sheet Properties. Orientation should be Floor/Ceiling and the U and V coordinates should be the same size as the pool you made before (400x175 if you used the same numbers as I mentioned before) hit build and you're set. Then align it correctly with the pool and put it a bit lower than floor level so it doesn't look like it's going to overflow. Now pick the water texture you wish to use and then click on the Add Special Brush button (four down on the right of the toolbar) on the predefined dropdown list pick water. Thanks to the Epic boys the hard part is done for you, the correct water settings. Hit Add Special and you are set. You should see a nice transparent brush in side the pool if not right click on the grid go to Rebuilder (F8) and in Geometry hit Rebuild Geometry (make sure that Auto BSP is not clicked). Bam! You have your water brush.

    Water Volume

    Ok now you have the top of your water now if you play your level you will see you can't swim around that is because we haven't added the Zone to make it seem like there is water. Now go to the Textures dropdown list and pick Classes, go to Info -> ZoneInfo -> WaterZone. Click on WaterZone and then right click on the grid where the water is (this should be BELOW the water texture) make sure it is correctly inside the pool. After you hit Add you will see a question mark with a cube. Now go to Rebuilder (F8) and Rebuild Geometry then go to the BSP tab and Rebuild BSP make sure Auto Lighting is not clicked. Lighting is optional in your case. If you want to go ahead and throw some lights in this shouldn't affect the water. After rebuilding Geometry and BSP save your level and play it. Viola you have a nice cool refreshing pool!

    Make it Alive

    Want to make your water move? Right click on the water texture and go to Surface Properties. You will see Translucent, Portal, and 2 sided checked, leave it checked. Now check on Small Wavy and click on close and there it should be done.

    Adding Sound (Optional)

    Your pool not good enough silent? Fine then right click on the WaterZone entity (the question mark and the cube inside the pool) Go to Properties and click on Sound. Click on Ambient Sound and it will say None, then click on the three periods and it will open the Sound list on the right for you to choose. None of the ambient sounds are loaded when you start up UnrealED so hit on load and choose the AmbOutside sound package. After it opens choose any of the water sounds you feel like picking. Then hit USE on the WaterZone properties menu and now your water has sound.

    Ending

    That is basically how you make your body of water. Experiment and mess around and you will learn a lot that way. It isn't hard at all it just takes time. Slime and Lava is basically the same just different Zone entities, if Lava and Slime tutorials are needed head over the feedback page and tell us.

    * - For textures that are animated already open the Liquids.utx. Then the textures don't need the surface properties of Big Wavy and Small Wavy. Thanks Rip.

    - Final water hole in Unreal -


Wolf's Tutorial Water

Wolf's Tutorials: Water

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Water

Water is one of the best looking effects with the Unreal Engine. To make water you simply make a zone, add a WaterZoneInfo, and give the "top" a water texture. That's basically it.

Simple Pool

Start by loading a texture set (whatever you like) and then loading Liquids.utx. Okay, pick a texture from the texture pack you selected (anything but a water texture) and then make a 512 x 512 x 512 cube and subtract it from the world.

Now, resize the red brush to 512 x 384 x 384 and position it against the floor in the middle of the room (like below) and subtract it. You should now have a huge pit in the middle of the floor.

RIGHT CLICK THE SHEET BUTTON AND SET THE SHEET SIZE TO 384 X 384 AND MAKE SURE FLOOR/EILING IS SELECTED. POSITION THE SHEET SO THAT IT FITS PERFECTLY OVER THE OPENING OF THE PIT AND JUST BELOW THE EDGE (SEE BELOW).

SELECT A NICE LOOKING WATER TEXTURE FROM LIQUIDS.UTX AND SELECT IT (MAKING SURE NO TEXTURES ARE SELECTED IN YOUR MAP). NOW CLICK ADD SPECIAL BRUSH AND FROM THE DROP DOWN MENU CHOOSE WATER (AND MAKE SURE ALL THE BUTTONS ARE SELECTED LIKE BELOW).

ADD THE SPECIAL BRUSH. NOW ADD A LIGHT AND A PLAYERSTART AND YOU SHOULD END UP WITH SOMETHING LIKE THIS:

NOW, IN THE BROWSER, GO TO CLASSES, INFO, ZONEINFO, AND SELECT WATERZONEINFO. ADD A WATERZONEINFO INSIDE THE AREA WHERE THE WATER WILL BE.

REBUILD YOUR LEVEL, SAVE IT IF YOU LIKE AND TEST IT. YOU SHOULD HAVE A NICE LITTLE POOL OF WATER IN THE CENTER OF YOUR ROOM. YOU CAN APPLY THIS TO ANY SIZE, SHAPE WATER ZONE. JUST MAKE THE AREA WHERE THE WATER IS TO BE, ZONE IT OFF, GIVING A WATER TEXTURE TO THE SURFACE OF THE WATER, ADD A WATERZONEINFO. THAT'S ALL THERE IS TO IT. YOU CAN NOW ADD EFFECTS TO THE WATER TEXTURE LIKE SMALL WAVY OR BIG WAVY TO GIVE IT MORE MOTION IF YOU LIKE.

NOTE: Some people will "intersect" their water sheet when adding it to an odd shaped pool. I have had much better luck (not to mention fewer BSP errors) by making the water sheet a square, but big enough to cover the opening of the pool and letting the rest "overhang."

Waterfalls

Waterfalls aren't that difficult to make. Making them look good takes practice. Use pictures of waterfalls as a guide whenever possible. I will teach you the basics on making them, but you will have to practice to make the "right."

Okay. Kill the old map (or save it if you like) and start a new one. Again, start with a 512 x 512 x 512 room. Subtract it. Now make your brush 256 x 256 x 512 and align on the floor as we did the pool. Subtract it and you should have a trench like below.

Now resize the brush to 512 x 256 x 32. Align it against one wall as shown below, then intersect it and then subtract it.

Now add water sheets (using the sheet tool and special water brush) to the trench (just like we did the pool) and the cut we made in the wall. You should end up with something like this:

Now add a WaterZoneInfo in the trench. Add light(s) and a PlayerStart and rebuild. You can go test the map if you like now. The water fall is there but sure doesn't look real does it? To make it look like the water is actually falling we need to set some texture properties. Select the waterfall texture and bring up it's properties. First go to the Scale tab and under Custom Scaling leave the U the same and set the V to something about 8ish.

Now go to the Effects tab and check V-Pan.

Note: Look at the water fall in the 3D view (making sure the little joystick icon is clicked in that view). Your water fall may appear to be falling "upwards." If this is true then got to the Rotate tab and click FlipV.

Your water should appear to be falling now. You can also set the v-pan effect on the "stream" to make it appear to flow.

Tips

The water fall we made works, but is not very realistic. First of all the water doesn't come from anywhere in particular and doesn't go anywhere. If we wanted this to appear real, we could make a ledge above for the water to be falling from and make an opening on the opposite wall for the water to be flowing into.

These are the kinds of things I was talking about when I said you would have to practice to make it right. There are several water textures in Unreal. Look around the different .utx files and find ones you like (GenFluid, Liquids, FireEng, HubEffects, etc...). Some work better than others for water falls.

Slime & Lava

Slime and lava are made the exact same way as water. just insert the proper ZoneInfo and select textures to match.

Note: A lot of people have been asking about rising water effects, to flood a room or something. You can't do this with the Unreal Engine without writing a script for it. You can make a moving water sheet, but not the zone portal. Zone portals are stationary in Unreal and cannot move. You can make it LOOK like water is rising or falling (using a moving sheet textured like water) but you have to keep it shallow enough that you cannot go under to find that it is not actually water at all.

Also, waterfalls should be made narrow enough that you cannot swim up them. If you have a water fall that is part of a water zone and it is wide enough (32 units I believe) you can "swim" up the water fall. This might be a neat trick in certain levels, but not very realistic.

If you test your level after adding water and the whole room is filled with water (not just "under" the water brush) then you have a zone portal leak somewhere. Check your sheets and delete and re add them if you have to. Protruding objects: You can make things sticking up out of the water, but you have to add them BEFORE you add the water sheet. You may stuff under the water after you add the water sheet (zone portal) as long as it doesn't touch the water sheet.

Using what you have learned

Play around with water and have fun. Try different things and see what looks good and what does and doesn't work. As always, if you have any questions e-mail me.

-Wolf

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


The Water Engine

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    This tutorial will explain how to use some of the features of the "water engine" and show you how to create animated water textures in making a water texture that is animated on a water texture that you either make in a third party software package, for the simple editing of a texture that come with Unrealed.

    For once I am writing this one at home, so I will be attaching a few good images with it, and I actually (wow) have the editor here so I can call up anything I like. I will start off in a quick little paragraph about how to make this base image. Ok, I am using a copy of PSP5 (Paint Shop Pro 5) as everyone can download a trial version and do exactly as I have done here. I have made a basic empty image 512x512 and used the spray can tool to make a base background a nice shade of blue. When I was creating this base color, I used the "ocean" setting to make it a little more "realistic" and less mundane. Then I made sure that the image was single layered, and had no transparency and made a selection from the middle of it that was about 3/4 of the image size, and perfectly square. Then from the selections menu, I chose "Convert to seamless pattern". When the new image showed up, I made sure that the image was 256x256 in size, and cut the colors back to 256. Having done that, I saved the new selection as a .pcx file (Ver 5) and closed PSP.

    Ok, that is one part out of the way. Into Ued :) I went to the "browse bar" and opened textures. (I.e. chose "textures" from the drop down list, that contains "Textures, Classes, SoundFX, Music" ). Then opening the "import" function right at the bottom of the tool bar, I found the file, and imported into Unrealed.
    The import button is shaded a light green here, to make sure that you are using the right one. Ok, in the next window, I have selected the right file (remember the one that you just made in PSP?) and in the next window I made the following selections.

    Ok here is what all the bits mean. The Name is what the texture will be called as a texture. The Group is what part of a package the texture will be situated in. You know like you can open up the "Ancient.utx" file, and it is split up into various categories, like "Floor, Roof, Wall" etc. Well, that is what the group section decides. Import the image into a Group called "Still".The Package is what the actual name of the package when it has loaded. Enter "Water_tute" for this texture, so that everything will be the same for easy reference in this tutorial.

    Do not change any of the other settings there, as they will not be required for this particular texture. Ok, assuming that everything went according to plan there, you should now see a nice little thumbnail of the texture that you made in PSP and it should be in a package called "Water_Tute" in the group "Still".
    This will be the still version of your water. In every map that you do, try to include a still part of the water, so that it allows the player to seethe difference between the still and moving water. I mean a puddle would not be animated (Unless you have stuff dripping into it Hehee).

    Cool easy so far innit? Hehe, that is the hard part...

    Ok, now click on the "New" button (Right near the import button in the textures browser) and in the window that pops up, choose the following selections.
    Name = Anim_1 : This is what the texture will be called, so it is a good idea to put the "anim" somewhere in the name for easy reference later on...
    Package = Water_tute : This should already be set, but just in case if it is something else, call it the same as you did earlier.
    Group = Animated : This should default to "Still" but change it to animated so that you can locate the texture easier later on. It is a good idea to store different textures in different groups (Hopefully have then arranged into some resemblance of order as well).
    Class = Wet Texture : This is where you will find the tools needed to create the particular texture that you want. It is a dropdown menu. Select the "Wet Texture" and leave the Size at 256x256 (It should be at that size to begin with). Click on the "Create the Texture Button" and start to make the fun stuff.

    You should see a nice large BLACK square and a Properties box. In the properties box, drop the "Water Paint" sub-menu (Click on the little + sign next to the name) and select "Source Texture" from it. Having your new package open, select the "water" texture (You know the one that you just made in PSP) and press the little "use"button in the SourceTexture menu-line.

    Your large "black box" should now have the image of the texture that you just did in PSP in it, and you can finally start on the fun stuff.

    Where you see "Drop Type" in the WaterPaint sub-menu, click on DROP_PhaseSpot and you will see a huge drop down menu.
    These are the cool water and wave effects that you can use in the texture to make it look like real water. Here is a quick list of what they do :

    • Drop Fixed Depth - This will make a little "dint" in the water that does not go up or down,but just stays at the level that you set it to. I find this one quite useless.

    • Drop Phase Spot - This will make a little drop in the water, that i just like having a drop of water falling into one part of the texture all the time. It will also keep a nice little circular wave being formed around the drop center.

    • Drop Shallow Spot - This will be just like the "Drop Phase Spot" although it is much smaller.

    • Drop Half Ampl - This is once again similar to the "Drop Phase Spot" but it uses exactly half the Amplitude that you have set (Explained later). The size is very close to the "Drop Phase Spot"

    • Drop Random Mover - This will make a little pattern of waves dance all over your image. It follows no pattern, and actually looks quite like a little water bug running about on the surface of the water. Very cool and useful.

    • Drop Fixed Random Spot - With that name, you might expect it to move about the texture, but it actually stay almost in the one place, only moving a little bit to the sides, so that it will make the waves collide with each other, thus making them look much more realistic, then if it were just in the exact same place each time.

    • Drop Whirly Thing - Damn, I think that name is soooo creative.... ;) Anyways this setting will create a little "drop" of water that moves about in a small circle (not a regular one though :) and looks very much like a little bug once again that travels about on the water.

    • Drop Big Whirly - Same as above, but bigger and makes bigger waves.

    • Drop Horizontal Line - Make a line that will go down into the texture. If you place just one of these, it will most likely look like it disappears soon, but if you place a LOT of them all over the texture, then you will see that it makes the texture look like it is all moving.

    • Drop Vertical, Diagonal 1 & 2 Line - Same as above, but the wave is in a different direction.

    • Drop Horizontal Osc - This will make a line wave (Like the above) but will actually keep the wave moving up and down all the time, so that it will make great looking waves on your texture. Very useful if you place even just a few on the surface, and let their waves meet and collide.

    • Drop Vertical Osc, Diagonal 1 & 2 Osc - Same as above, but in a different direction.

    • Drop Rain Drops - This will make a random drop fall in the general area of where you click the mouse. Very nice and useful.

    • Drop Area Clamp - This will "raise" a part of the texture and make it look like there was a pipe under it pushing water up into the surface of the water. I have found very little use for this one.

    • Drop Leaky Tap - This will make a drop fall into a set place (where you click) and it will keep dropping there in a steady and "leaky tap" like manner.

    • Drop Drippy Tap - Damn, who makes up the names eh??? Anyways, this is just like the one above, although the drops seem to come about twice as fast. Very useful.

    Right that covers all of them.

    There are a few other setting in the screen though, so I better explain them eh? Ok. Another list methinks ;)

    • FX Amplitude - This does not seem to do anything at all :( Please correct me if you find it to do something, but I have not noticed any changes between 1 and 255.

    • FX Depth - By the name, I would guess that it denotes how deep a particular wave will go, but once again, I have found it to do little.

    • FX Frequency - This sets how many times your particular will be shown in each cycle. I mean the higher the number, the more waves will be generated in a period of time. They will be no bigger, or cover a large area, but merely more of the will be made in the same amount of time.

    • FX Phase - This one doesn't seem to be doing anything right now, but I have used it before to change the speed of the actual animations of the waves that are created (although that was in another part of the water painting program).

    • FX Radius - This will not work with all drop types, but I think that in general, you will be able to use it for "semi random" drops like the Rain Drops wave, to restrict the size of the area effected by it.

    • FX Size - Similar to the above. There are times that it seems to work, but other times it does nothng (like now) so I am guessing that it will only work for certain wave types.

    • FX Speed - Once again as the above.

    • FX Time - This will determine how long certain waves functions take to finish. It doesn't work with all the wave types though.

    • Wave Amp - This decides how "deep" the wave itself will be, and how far up and down it goes. The bigger the number, the bigger the wave made will be. Seems to work for all the wave types.

    Ok Now that one is outta the way as well :)

    To use the different wave types, simply click on the image map when you have the right wave type selected and it will be placed there. Really easy innit? Hehe, I told you making the right texture was the hard bit.

    When you have made the waves on the surface of the image Simply close both boxes and you will have the new texture ready for use in the level.

    One more thing, and this would be the most important bit. Save your package to the Hard drive. Heh, you might think that you already have the package saved, but this is not the case. Please for the sake of your textures, make sure that you save the file as soon as you finish making a new texture for it. To save the .utx file, press the button called (surprisingly enough) Save. Then you will be able to name the package file that you can then load into any level that you like, and you will also be able to send the files to other people to use.


Advanced Water

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    Forward:

    I did the intermediate water tutorial last night, and I want to get all the cool things that can be done with water off my chest...

    Abstract:

    This tutorial will pick up where the last water tutorial left off. I will explain how to make water surfaces move, how to place multiple water "openings" and how to make things jut out of the water level without spoiling the rest of the surface - and anything else I can think of while I am typing...

    Assumptions:

    I assume that you know a fair bit about UnrealED by now, so I won't go into as much detail about where things are - just how to do things...

    Tutorial:

    Introduction:

    Now that you have mastered what was in the first water tutorial, you probably want to add more cool water effects into the level, so here goes.

    Adding more then one exit from a water source:

    This is actually quite simple, to have a water source with more then one exit, all you need to do is create the "hole" for the water to go into, and then place the required water "sheets" (I mean the water planes) and then add a water zone in between them. It is really not an advanced step, but most people NEVER tell anyone that it is so simple...

    Making the water surface "move":

    Once again, this probably could go into a simpler tutorial, but I didn't put into the first water tute, so it goes here... If you don't want a surface texture from "liquids.utx" (they will bog down slower pc's - or for whatever reason) but you don't want the plain simple water textures that are found through the rest of the textures, then select one (of the plain ones that is) and when you have placed it where you want it to go, select the surface (top and bottom) and bring up the advanced texture options. Click on "Small Wavy" or "Big Wavy" and it will move from side to side, and up and down. This adds a lot of realism, but won't chew nearly as much resources as an animated texture...

    Waterfalls:

    Waterfalls are really cool. A waterfall does look best when it does fall into a pool, so when you have a pool - and a nice ledge, crevice, cranny (whatever) for the water to come from, create a solid cone or a rectangle (whatever shape will look best for your setting - but do it using the "sheet" tool) and select the add special brush as you would normally do, select the water plane (as you would normally do) and then place a "waterzone" in the middle of the shape. If you build it well enough, you may not even have to use two separate water zone, just use the one from the pool of water. Now select the sides of the water, and bring up their texture properties. Under the "scale" section, make sure that they are stretched going up and down, then go to the first tag and make them "pan" going down. If your waterfall is in a cave, you might also want to give it a fair amount of fog around the base, but if it's out in the open, then go easy as it may drain a lot of system resources. Waterfalls should not allow players to swim up them, so you will need to either make it a narrow size, or alter the gravity setting under advanced properties. A setting of a million (1000000) I think ( I hope I remember correctly) should do the trick, alternately set a gravity that pushes a player to the front or back of a waterfall. Lastly waterfalls need a waterfall sound, Furthermore, you should put a ambient sound in the "waterzone" AND around it. This will let the waterfall be heard from a distance and whilst a player is underwater.

    Protruding objects:

    This is easy, but it requires a trick to perform. That is, the water plane MUST be added AFTER all the rocks (or whatever) are put into the water surface. I mean, if you have a pool and you want to place a rock or two jutting out above the water level, you have to place the rocks into the "water" before you actually place the water sheet into the pool. You will also HAVE to deintersect the brush before you add it into the map, otherwise, you WILL get horrible effects.


Liquids

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    Forward:

    Okay, Here comes an easy tutorial on how to make water...

    Abstract:

    Making water is VERY easy, but you have to know how to do it first...

    Assumptions:

    I assume that you know how to make basic rooms.

    Tutorial:

    Introduction:

    Water adds a lot more depth to a level, whether it be in the form of a pool, a puddle here or there or perhaps a whole "Flooded In" level, with air pockets here and there... I assume that you have a level where you want to place water, so you should start off with a room already...

    Creating the water "hole":

    Just as you would normally create a room, or a hallway or whatever for that matter, "cut" out the space for the water to go. I mean if you want a pool in a certain room, then make the room and cut out the place where you want the water to go into. If you are just starting out, it's a good idea to stick with simple things first, maybe a small square pool.

    Adding the water sheet:

    Now that you have a place for the water to go, select the sheet* brush. When you see a thin red line, simply select the sheet properties (right click the sheet button) and select Floor ceiling orientation. The size of your brush should be a little larger then the hole you created for the water level (ie. It should actually overlap the sides). Now place it just below the level of the sides - otherwise it looks like it's going to overflow) and hit the "intersect" button (the fourth one down on right hand column). This will then make the brush fit your water level EXACTLY. At this point you might say why not just make the same dimensions, right? Well that is because if later down the track, you want to add in things like rocks jutting out of the water, or you have water levels that are not rectangular, you will already know how to make the proper brushes for them - rather then having to learn a whole new method. Better to get it right the first time. You will have to load in the textures for water, so under the texture bar, select "load" and scroll along until you find "liquids", load it and choose a water texture for the sheet you want to build. Now that you have the sheet the right size, and in the right place and with the right texture, click "add special" (the fifth button down right hand column) and from the drop down list, select water. Simple isn't it??? At this point, sometimes - the water sheet won't show up - if this is the case, just "rebuild" the level, and it will be there.

    Creating the water itself:

    Now that you have the water sheet, you can add the zone info for water... Where the texture bar is, select "classes" from the drop down list (it should currently display "textures". Choose info>zoneinfo>waterzone and right place it into the area your pool is in (right click in either a 2D or 3D view) and make SURE it is inside the area you want the water to occupy.

    Adding sound:

    When you select the waterzone info and place it into the map, it will automatically add some sound into the water for you, but you can change the actual sounds that you hear by bringing up the waterzone properties (right click the waterzone icon - the cube with a question mark next to it). Then select "sound" and choose "ambientsound" this will then bring up some buttons. Click the 3 dots and you will be shown a list of sounds to choose from. If you haven't loaded any sounds, they won't be there yet, so to load them click the "load" button below the "sounds" bar and choose "AmbOutside". Then in the drop down list select "water" and play them until you find one that will suit your needs. Go back to the properties and under AmbientSound, choose "use". That's it, Done.

    Rebuild and Play:

    Simply rebuild your level, and play it to check out your water settings. To see more cool things that can be done with water, look out for the "Advanced Water tutorial that I will be posting shortly.


The Wave Engine

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    The wave engine in the editor is a great thing that does not seem to have been used in the actual Unreal Game. I have made quite a few water textures using this method, and I think (so do all the people that have seen them) that this type of water is much more realistic for outdoor areas, and has that "real water" feel to it. It will also make the impression that the water in the game is moving up and down and has little waves all over it. Well enough blabbering, time to get to the tute eh?

    Opening up the Wave Engine

    Ok, this is really easy. To open up Wave Engine, all you have to do is to go to the "textures" browser, Click on "NEW" and you will see a little dialog box appear. There are a few options here.

    These options are basically what you will need to get you in. Here is a list of what each "setting" will do.

    • Name : This will determine the name of the texture when you have the texture package (.utx file) open in the editor.

    • package : This will be the name of the texture package when it is inside the editor. Note that this is not the name of the actual file.

    • Group : This will be the name of the group that the particular texture belongs to. You know how you can open up the Unreal textures, and they are nicely divided into things like "Roof, Floor, Walls" etc? Well that's how it's done. Enter the name of the group that you want the texture to be in. If you want it to be in a group that already exists, just enter the name of the group (Case sensetive) and it will be there.

    • Class : This is the type of class that the texture will be. For this tutorial, make sure that you have "Wave Texture" selected, otherwise you will have serious problems tryin to follow what is going on ;-)

    • Size : This is going to be the size of the texture that you make (in pixels). Most of the time, you will want a larger texture, although you could of course use a small one (say 64x64) if it's going to be repetitve, or placed on a small item. I would however suggest that textures to be made for general purpose (and certinaly for this tutorial) are at least 256x256 large ;->

    • Create this Texture : Well, this is the wonderful button that you will want to press when you have entered in all the stuff that you have to enter in. Simply really :)

    • Cancel : If you don't know what this will do, then I ain't gonna tell ya. Hehee

    Ok, now that we got that out of the way, we can actually start to do some cool editing here.

    This is what your screen should look like now. Ok, you got that? Now there are a few things that I will explain first. Here is a lit of what you will be playing with. Click on any of the entries to change their values. This image will explain what I am talking about here.

    • Bump Map Angle : This setting will determine what angle the Map will be "bumped" from. Not all that important really from what I have found. It seems to go very wierd if you set it to high levels (above 230) and also mkaes your phongs dissapear if it is set to a very low level.

    • Bump Map Light : This setting will determine just how much light there is on the Texture. It has got nothing to do with where lights will be placed in the actual game, just while you are making the texture. The more light there is, the lighter the water will be, and the less Phongs you will see (Phongs are explained later). I would suggest that you keep the Light at either the level that it starts off at, or add in a little more. Dark waters tend to look too black to be realistic, but everyone to their own eh? This setting bar will be brightest at 128. The scale will work in such a way that 0 is pretty much black water with little "phongs" of light (Yes, I will explain them in a sec) appear on the tops of the water, 128 is the brightest level possible with the water being almost white and the waves showing up nicely, and 255 will set the water to show waves once again, but there will be no Phongs Visible at all.

    • Drop Type : This will choose the type of "brush" you will be using to "paint" the waves onto the water. This is a drop menu, and there are heaps of options in it. I will list them all and what they do further down. Right now, all you need to know is that it chooses the type of drop/plop/gloop that you will be adding to the water.

    • FX Amplitude : Sadly, this feature does not seem to do anytihng right now. Perhaps it is a setting that will be implemented in the retial version of the editor.

    • FX Depth : I cannot find a real use for this entry, as it does not seem to change anything. I might be wrong, and if you find out what it doesn, then please tell me so that I might be able to explain it here, but until then, it gets a "Not Here" rating.

    • FX Frequency : This setting will change the speed at which the waves are produced from the actual wave brush. Ie, if you make an Oscillating Horizontal bar, and set it to 8 (The defualt) then you will get say, three waves every second. Set it to 32 and you will get 12 waves a second. This will not make the waves any larger, or higher, or make them cover a larger area, just will make more of the appear each second.

    • FX Phase : Well, here is another "I don't know if it does anyrthing" setting. It does not seem to make any real changes when you are playing with it, but Once again, if someone finds what it does (or knows) then please drop me a line, and I will correct myself here :)

    • FX Radius : Well, I would have thought that this setting would alter the radius that "random" water brushes (like rain drops) take the value of. Ie a larger number would make the rain fall into a larger area, but this does not seem to be the case. It doesn't seem to do much at all. Perhaps I am using the wrong bursh here, but I have tried it with MOSt of them, and it has done nothing. Oh well, I guess we are using a BETA editor eh?

    • FX Size : This one, I can tell you what it does :) When you change the setting here, it will change the size of the brush that you are using to "pain" the waves with. For example, if you choose a small setting (like 4) and use a vertical osillating brush, then you will make a waves that looks almost like a drop of water, but if you change the setting to say 32, then it will mkae a brush that is almost a quarter of the texture. This setting comes in handy when you want to make a wave texture that is not "repetitive" and so that you can make it look more natural and make the waves vary in size ond shape.

    • FX Speed : Ok, this one has got me beat. Sorry, No real idea what (if anything) it changes.

    • FX Time : Unfortunately this feature does not seem to be implemented here. I have once again tried it with a few different brushes, and it seems to make no difference to anything. Perhaps someone out there knows what it does, and want to mail me to tell me?

    • Phong Range : Well, I said that I would tell you what this means so here it comes. A Phong is the little bit of light that is reflected off a wave as it passes along near a light, or with a light behind it somewhere. When you have looked at the ocean or a lake, you will see that the water is full of little "glints" of light, and there is always a little bit of a sparkle somewhere. Well, this is called a Phong. The Phong Range setting basically determines how far away from the center of the brush, this particular phong can travel. If you play with just one oscillating brush, you will see what it really does. I would suggest that you set it to something small (like 4) and make a wave. You will see it right near the actual center of the brush but it will not travel all the way with the wave. If you set it to a higher number (like 128) then you will see that it should travel along with the wave to almost (if not all the way) to the end of the actual wave. Phongs will also be created when you have waves meet each other to form new waves.

    • Phong Size : This will determine just how large a phong is on a wave that is made. You can make the phong very small (like 4 or 8) and you will only see a small glimmer on the crest of the wave, or you can set it to a high number (255?) and you will be able to see that almost half the actual wave is covered in a bright light (ie the phong). I would suggest making it a fairly small number so that the glints look realistic, and not like they are all over the place, and I would also plan ahead and choose just how much light will be falling on that particular texture. If it is a small amount of light, then I would only use a few phongs here and there, but if you want to place the water right in the middle of a brightly lit up courtyard, then have a fair few of these things floating about, and it will enhance the effect of the lights, especially if you have water somewhere else that is a lot more "dull" so to speak.

    • Wave Amplitude : Well this one is easy :) This setting will determine just how large your waves are. The higher the number, the deeper and higher your waves will be. A low setting would be great to use if you want to make a water texture look as if it is almost calm, and a high setting would be good to use near a water fall. Play and see with this one, as it depends completely on what type of water you are trying to make.

    Ok, that pretty much covers all of the settings. here is a list of what each of the differnt drop types do. There are a lot of brush types to use, although most of them are actually just alterations of each other.

    • Drop Fixed Depth - This will make a little "dint" in the water that does not go up or down, but just stays at the level that you set it to. I find this one quite useless.

    • Drop Phase Spot - This will make a little drop in the water,that i just like having a drop of water falling into one part of thetexture all the time. It will also keep a nice little circular wave being formed around the drop center.

    • Drop Shallow Spot - This will be just like the "Drop Phase Spot" although it is much smaller.

    • Drop Half Ampl - This is once again similar to the "Drop Phase Spot" but it uses exactly half the Amplitude that you have set (Explained later). The size is very close to the "Drop Phase Spot"

    • Drop Random Mover - This will make a little pattern of waves dance all over your image. It follows no pattern, and actually looks quite like a little water bug running about on the surface of the water. Very cool and useful.

    • Drop Fixed Random Spot - With that name, you ight expact it to move about the texture, but it actually stay almost in the one place, only moving a little bit to the sides, so that it willmake the waves collide with each other, thus making them look much more realistic, then if it were just in the exact same place each time.

    • Drop Whirly Thing - Damn, I think that name is soooo creative.... ;) Anyways this setting will create a little "drop" of water that moves about in a small circle (not a regular one though :) and looks very much like a little bug once again that travels about on the water.

    • Drop Big Whirly - Same as above, but bigger andmakes bigger waves.

    • Drop Horizontal Line - Make a line that will go down into the texture. Ifyou place just one of these, it will most likely look like it dissapears soon, but if you place a LOT of them all over the texture, then you will see that it makes the texture look like it is all moving.

    • Drop Vertical, Diagonal 1 & 2 Line - Same as above, but the wave is in a different direction.

    • Drop Horizontal Osc - This will make a line wave (Like the above) but will actually keep the wave moving up and down all the time, so that it will akegreat looking waves on your texture. Very useful if you place even just a few on the surface, and let their waves meet and collide.

    • Drop Vertical Osc, Diagonal 1 & 2 Osc - Same as above, but in a different direction.

    • Drop Rain Drops - This will make a random drop fall in the general area of where you click the mouse. Very nice and useful.

    • Drop Area Clamp - This will "raise" a part of the texture and make it look like there was a pipe under it pushing water up into the surface of the water. I have found very little use for this one.

    • Drop Leaky Tap - This will make a drop fall into a set place (where you click) and it will keep dropping there in a steady and "leaky tap" like manner.

    • Drop Drippy Tap - Damn, who makes up the names eh??? Anyways, this is just like the one above, although the drops seem to come about twice as fast. Very useful.

    Right, that is out of the way. Now to actually paint with the stuff, all you have to do is to choose a wave brush (one of the things in the list above here) and click on the blue texture box. This is the box that has opened itself along with the properties bar. Nothing that hard there really is there? heh. Enjoy and make good water.


BB Drac - Unreal Tournament UED2 guide Zone, Water/Lava

Water / Lava

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Create a fairly large room (512x512x512?) and texture it as you feel.

To create the waterhole you need to subtract a small area from the ground.
A suggest you subtract a 256x256x256 sized brush.

Screenshot

When done we need to seal off the area we want to use for water.
This is best done with a sheet brush.

Create a sheet brush sized 256x256 in AX_Horizontal.
Place the sheet close to the top of the hole.
I placed it 16 units down.
(If you place it 32 units down people will start having trouble getting out).
Make sure that the sheet actually fill the hole and not overlap somewhere, or
you will fill everything with water.

Now load the textures "liquid1.utx" and select a water texture you like.
Press the "AddSpecialBrush" and select "Water" as Prefabs.
Leave the rest and press "Ok".

If the "water" didn't show up? Don't worry, just rebuild and it will be
there

.
Screenshot

So far we have only done the visual stuff.
To add the water itself you must open the actor browser.
Under "Info" and "ZoneInfo" you find "WaterZone". Select it and close the
actor browser.

Now place this "WaterZone" inside our hole, and under the sheet.

Screenshot

When done simply rebuild the level.
Add a playerstart if you want to try it and rebuild.

If you wanted to create lava, acid or slime instead, you do exactly the same but
instead of placing a "WaterZone" you must place the correct zoneinfo actor.
You also should change the texture ("fireeng.utx" has some lava if that is what you need)


Creating Water in UnrealEd2

Creating Water in UnrealEd2.0

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: maverick@planetunreal.com

Saturday, December 29, 2001 9:55 AM

Forward:

I have been asked to write a tutorial on how to create water, so I am doing so, though this tutorial is quite widespread, I do it because the person asked me to.

Abstract:

This will teach you how to make water in UnrealEd2.0, it can be used to create other liquids, such as lava and slime, as well.

Assumptions:

I assume you know the basics, and a little beyond.

Tutorial:

Create a room, 1024x1024x1024, and add a texture, and texture you want, preferably a wall or base texture.
Now, resize your builder brush to 64x512x512 and align it with the bottom of the first room you created. Subtract that, and repeat, but this time with a brush 128x256x256, from the bottom of your second brush. It should look like this:

This is what it should look like, click to see a larger screen.

Once you have the room created, it's time to create the water. Doing this is quite easy, all you do is click on the 'Sheet Brush' button, and set it to 512x512 with an axis of AX_Horizontal.
Now, load the texture package Liquids.utx (This is your biggest texture package for water), or HubEffects.utx (this has some nice liquid textures), and select one you like.
When you have selected the texture, move the brush so that it's just below the top of the 2nd box you created, like this:

Your water should be placed right below the top of your 2nd box, so the water is below the rim. Click to see a larger image.

(A tip, rightclick on the grid, and change the grid size to 8 or 4 to move the brush closer to the top of the rim, rightclick and change back to 16 after you are done).

hit the 'Add Special Brush' and select from the dropdown menu 'Water', then click OK. A sheet of water should now appear like this:

The sheet of water is now there. Click to see a larger image.

If water does not appear, then make sure your camera is inside the box, if you are outside of the zone where the waterbrush is in, it will disappear. If you still don't see anything, rebuild, it should appear.
The waterzone sheet brush should be green.

We are not done creating our water just yet, if you try to play right now, you'll fall through the sheet and hit the bottom like there was just air there. We need to add a 'WaterZone', which can be found under Info, then ZoneInfo.
Select the WaterZone and add it below the sheetbrush, so that it is in the are below the floor. The ZoneInfo should look like a Question Mark (?). Your map should look like this:

The WaterZone is the ? Mark looking thing. Click to see a larger image.

Once you have added the ZoneInfo into the level, add a playerstart, and rebuild the level. You should have a nice little swimming pool or whatever you wanted it to be.

This tutorial is Copyright of Tyler A. Perry AKA Maverick, please do not copy any part of this without getting permission. Thank you.

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


Water

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers :

Adding water to your level

Forward:

Sorry , i cant be bothered going in to too much detail , but if you ask nicely , i might add some more pictures and make it easier to understand etc

Content (or whatever):

This is pretty easy to do. First of all , get a level ready to try this out. It can be something you've whipped up in a few minutes or your life-long masterpiece. It doesn't matter. Anyway , make a trough some where in the level (for a below-ground pool) , to do this , just make a cube with dimensions how you like or use the 2D Shape Editor (the mappers best friend) and put it level with the bottom of your level then subtract it. Then make a sheet *BIGGER* than the troughs length and width (or for precise measurements use the same shape in the 2D Editor as before) and place it BELOW ground level , below the top of the trough. *See picture* (Before adding the brush like this)

picture already has water in it! woops!

Before doing this next bit , select a nice water texture.I find that the best ones are in the GenFluid texture package.*Next bit*- select "Add Special" from the menu on the left (under add and intersect) and from the drop-down menu that appears select water (dah!). Then go to Actor Classes>Info>ZoneInfo>WaterZone . Right click *INSIDE*
your trough and select AddWaterZone . Then rebuild and you're done! You will now notice that your sheet has turned green in the 2D views.This means that it worked. But make sure that your waterzone is UNDER the sheet. If it is above the sheet , it will flood the whole level. And make sure that your sheet is bigger than your hole/trough because this also lead to flooding. Once again , feel free to experiment because that's how you learn! Oh and just a little interesting thing : Unreal Tournament does apply the rules of gravity.....with that in mind do some more experimenting! Floating water is always funny to see....

But here is what it should have turned out like :

Note: I will update this tutorial soon. (The date is 8.01.02) Email me to tell me what else

you would like to see in this tutorial.

About the tut: I decided to write some tutes because of the fact that nearly every tut on the net has been written for UEd1 and that really pisses me off..... sorry about that , but that's the truth. I apologize for the use of so many brackets , but that's just the way I "write".

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Rising Water

by: IceLord (NL)

icelord_nl@hotmail.com

UnrealED 2.0 Tutorial: Download .zip

Almost everybody who knows how to make water, lave or slime sometimes thinks about making the water rise.Many have tried, many have failed, but here's a way to actually do it: making the water rise.

But first I'd like to thank Wolf for his WZTriggerExample map, and Scott 'Slasher IV' Kircher for his scripting talent.

The concept of rising water:

To explain the concept of rising water I have provided an example map. In this example map when we press the button the water will rise, filling the hole in the ground with water.The boxes will float and you can swim (and drown) in the water.

- Copy the example map to your C:\UnrealTournament\Maps directory and startup UT.- Start a Practice Session, set the GameType to Tournament DeathMatch, select DM-RisingWaterExample as your map, set the number of bots to 0, and click on Start…

So now your have seen with your own eyes that the water rises, we will go into some more detail.

The concept of rising water is pretty simple, all I needed in this example is:

  • One Button (Tag is irrelevant, Event = Dispatcher)
  • One Dispatcher (Tag = Dispatcher, there are several Events)
  • One Watersheet converted into a Mover (Tag = Water, Event = None)
  • Several TriggerWaterZone info's (Tags = Level1 to Level 5, Events = None)

When you open the example map in UnrealED 2.0, you can see the Button (the purple box), the Watersheet (the purple sheet), the Dispatcher, several ZoneInfo's, a Light and the all mighty Playerstart. You can also see that the Button and the Dispatcher are connected with a red line.

When you select the Zone/Portal view in your 3D View, you can see that the hole in the ground is divided into 6 Zones. In the lowest zone there is a normal WaterZone, the other 5 Zones are TriggerWaterZones.

So, what really happens when we push the button?

Obviously, the Dispatcher is activated (remember the red line that indicates that the Button and the Dispatcher are connected?), so open up the Properties of the Dispatcher. Under Dispatcher there are the OutDelays and the OutEvents.

In the OutEvents are all the events that happen when the Dispatcher is triggered, in the OutDelays are the time-delays (in seconds) that occur before an event is triggered.

So, looking at the first Event (that's the event next right of [0]) we see "Water". "Water" is the Tag of the Watersheet. Looking at the first delay, we see that the delay is 0 seconds (meaning that the Watersheet will move (rise) immediately after the Dispatcher is triggered).

The other events are Level1 to Level5, with each a delay of 1 second.

Level1 to Level5 are the Tags of the TriggerWaterZones.

So if the Dispatcher is activated, the Watersheet will move, and the TriggerWaterZones will be activated, one by one.

Since the Button can only be activated ONCE, there is no turning back…the water will stay.

The TriggerWaterZone: Download example map

Wait a second, we don't have any TriggerWaterZone Info's in UnrealED!!!

You are right, you don't have them right now…but you will soon.

So get ready for some scripting!!!

Follow me:

    1. Startup UnrealED 2.0

    2. Open up the Actor Class Browser Info ZoneInfo WaterZone

    3. Rightclick mouse New…

    4. Package: MyLevel

    Name: TriggerWaterZone

    5. Copy the following lines into the script (overwriting all the text there is):

//=============================================================== ==============

// TriggerWaterZone.

// This class allows you to change a zone from a Regular Zone to a Water Zone

// using the normal trigger method.

// Created by Scott 'Slasher IV' Kircher

//=============================================================== ==============

class TriggerWaterZone expands WaterZone;

function PostBeginPlay()

{

Super.PostBeginPlay();

if(!bWaterZone)

{

ViewFlash=vect(0,0,0);

ViewFog=vect(0,0,0);

}

}

function Trigger( actor Other, pawn EventInstigator )

{

local Actor A;

local Pawn P;

local Decoration D;

local TriggerWaterZone oldself;

oldself=self;

if(bWaterZone)

{

bWaterZone=false;

ViewFlash=vect(0,0,0);

ViewFog=vect(0,0,0);

ForEach AllActors(class 'Actor', A)

if(A.Region.Zone==oldself)

{

ActorEntered(A);

A.ZoneChange(self);

if(A.Buoyancy>0.0)

{

A.SetPhysics(PHYS_Falling);

}

}

ForEach AllActors(class 'Pawn', P)

{

if(P.HeadRegion.Zone==oldself)

{

P.HeadZoneChange(self);

P.PainTime=-1.0;

}

if(P.FootRegion.Zone==oldself)

{

P.FootZoneChange(self);

}

}

}

else

{

bWaterZone=true;

ViewFlash=Default.ViewFlash;

ViewFog=Default.ViewFog;

ForEach AllActors(class 'Actor', A)

if(A.Region.Zone==oldself)

{

ActorEntered(A);

A.ZoneChange(self);

if(A.Buoyancy>0.0)

{

A.Velocity.Z+=1;

A.SetPhysics(PHYS_Falling);

}

}

ForEach AllActors(class 'Decoration', D)

if(D.Region.Zone==oldself)

{

D.bBobbing=False;

D.Bump(self);

}

ForEach AllActors(class 'Pawn', P)

{

if(P.HeadRegion.Zone==oldself)

{

P.HeadZoneChange(self);

P.PainTime=P.UnderWaterTime;

P.SetPhysics(PHYS_Swimming);

}

if(P.FootRegion.Zone==oldself)

{

P.FootZoneChange(self);

}

}

}

}

    6. Compile the script with hitting F7

    7. Close the script

    8. In the Actor Class Browser click on View and select Show Packages

    9. Select MyLevel and click on Save Pkgs.

That's all for the scripting part, so one big thank you for Scott 'Slasher IV' Kircher!

If you have read the comments of Scott, you may have noticed how the TriggerWaterZone works.

The TriggerWaterZone can be triggered (duh!) from a normal Zone into a WaterZone (and back!!!).

Aha! So when the Dispatcher triggers the Levelx events it activates the TriggerWaterZones, turning those zone into a WaterZone.

The rest:

The rest is simple.

I have divided the part where the water will rise in 5 parts (using Zone Portals) and put one TriggerWaterZone in each part.

I gave the TriggerWaterZones different Tags (Level1 to Level5) AND under ZoneInfo in the Properties of the TriggerWaterZone I turned the bWaterZone to False, because I wanted the level to start 'dry'.

(If you want to have a part of your level that is flooded at first and can be drained with a button, leave the bWaterZone to True)

(If you want to make a level where you can drain/flood the same part over and over again, take a close look the triggers in the example map from Wolf.)

I placed a Dispatcher, which activates the Mover (the Watersheet) and the TriggerZones (one by one).

I made a Button, which activates the Dispatcher.

(The Button can only be triggered once, so that the Dispatcher can not be activated again.)

You can add sounds to the rising water (just like if it was an elevator or door) to make it more realistic.

Summary:

Divide the part of your level you want to be flooded/drained into several Zones (using Zone Portals) and place a TriggerWaterZone in each part.

(Set bWaterZone to False if you want the TriggerWaterZone to be dry at the beginning, or leave it to True if you want that part to be filled with water at the start.)

Make a Watersheet (make the texture Unlit and Transparent) and turn it into a Mover (either with Polygons To Brush or with Intersecting a larger buildingbrush).

Set up a Dispatcher, which will activate the Mover (the "water") and all the TriggerWaterZones (one by one).

Set up a trigger (button) that activates the Dispatcher.

Add sounds.

Good luck,

IceLord


Skyboxes

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    I have been asked quite a few times about skyboxes, so this tutorial should hopefully explain just what is the go with em ;)

    Assumptions

    There is nothing really all the hard about skyboxes, so I am assuming that if you want to build a basic skybox, then you should easily be able to follow what I am talking about here.

    The Theory

    A skybox is simply another place in the level that will show up as the "outside" edge of your level. You will often see a nice level that is based in the underground, and with a few places that show light (or the sky) and yet they all look identical, and seem to actually be made of the same sky. This is because the thing that the player is seeing IS the same piece of sky. A lot of people who start making a level, and try to have a nice sky will try to create a Sky for each part of the level, but this is certainly the wrong thing to do here. Wouldn't it be so much easier if we were able to create a little "room" with a sky in it, and then simply click on a property of a texture, and say "Don't show this texture here, but show what is inside the little room with the sky in it". ? Well that is basically just what we can do.

    The Sky Itself

    To make the sky itself is probably the hardest part. Sure, it's easy to make one that will do the trick, but it's a lot harder to make a really good looking sky that is worthy of a real level.

    There are a few guidelines that you should stick to when you are making a good skybox.

    • Size
      The size of the actual skybox is the most common mistake that is made by people when they first start. Most people assume that the skybox will have to be large enough to cover the entire "sky" of the level itself. This is not the case at all. It is a norm to make the skybox about 1024x1024x768 or that is the size that should work well with most levels. This is large enough not to get too tricky, but at the same time, it's also not too large to start getting messy with lights and the like, and will not hog too much system resources when the level is being played.

    • Shape
      Did anyone ever say that the shape of a skybox HAD to be an actually "box"? No! I do often use a box for simplicity, but if you have a level that will only be showing one side of a skybox, what is to say that you can't make it in a wedge shape, or perhaps a nice spherical shape? There are limitless possibilities that you can use here but I just wanted to point that out, as it seems to be a "assumption" that most people make - wrongly.

    • Lighting
      Lights are of course very important to use in a skybox, and there are a number of things that you will want to consider before you start throwing them in.

      • Dynamic Lighting : While there is nothing to say that you can't use dynamic lights in the skybox, and they certainly look really nice, you will find that they are actually rarely used in the main Unreal levels, as they do hog resources like little else. Think about just how much resources Dynamic Lights can use when they are in a level itself. If you use one that is slightly larger you will notice that it will really bog down a smaller machine, and the same goes for their use in a Skybox, although it is actually multiplied somewhat. When you place on in a skybox, it greatly increases the amount of resources that will have to be assigned to it, and can really slow down a smaller unit when the person is playing. This is one of those tricky things however, because if the level generally plays VERY well, and the skybox will only bee seen from a place that has little "happening" around it, then sure, throw something nice in and give the players a little more eye candy, but if you have a huge open (or outdoor) level where the skybox is seen from a lot of places and there will be fighting etc, then you might want to hold off the eye candy and simply go for better playability.

      • Fog : Please don't use fog in your skybox. It won't work. It will however still slow down your level quite a bit. The reason that you level will slow down but the fog won't be seen is simply because to see fog in a level it the player HAS to be in the same Zone as the fog. Now if you place fog into the skybox, you will still have the fog there, and if by cheating the player actually "flew" into the skybox, then technically yes, it could be seen there, but if the player is normally playing the level, they would of course not be in the same zone as the fog, so it would not be seen at all. However because the fog "technically is there", the PC still has to do all the horrible calculations for it, in the case that the player was to fly into the area. Once again, I am simply going to say Don't!

      • Colored Lighting : Colors will normally add in quite a bit to make your sky look a lot nicer, and it will also not hog too many system resources. Most good skyboxes (You know the ones that you stare at for ages, until some monster creeps up and shoots you, at which point you have to "snap out of it" and start playing again) will use quite a few colors, and you might even hint that they are somewhat "psychedelic" if you look at them for too long, and try to "work them out", but if you simply look at them, then you will think "Yikes, what a lovely sky there is here...". That is the effect that we are trying to get here. Feel free to use lots of nice colors in your sky, and if you want to have a level that looks realistic rather then painting it with splashes of many colors, why not create a sunset, or sunrise and have the sky painted with a myriad of yellows, oranges and reds.

    • Movers
      You can place movers into your skybox, but once again, it can be a little straining on resources and keep in mind that whatever you put there, will most likely be MUCH larger when you see it in the actual game. However a good use of a mover in the skybox, is a VERY good way to add in that little "extra" to make your level stick out above the normal that most people are putting out. For example, if you have a good level that is set in a futuristic timeframe, why not create a space ship, or fighter plane (whatever) that is triggered by something in the level, and it flies across the sky, then disappears not to be seen again. If you have played Quake 2 (I guess that most people have done so) you will most likely remember the first level, when there is all sorts of broadcasts going on, and you can see and hear the fighters as they fly over the base, then are not seen again. This may seem like a LOT of work for one simple thing that will never be seen again, but the "shiver" that most player will get, will be worth the work you put into it.

    The way to make a skybox.

    I have left this to last, as I really wanted you to read all of the stuff that I have written about them first, and to keep it in mind as you are creating your own sky box, as all of the stuff there has been learnt from many hours both playing and editing levels, and it would seem like an awful waste for you to read this bit first, then miss out on all of the "little tricks" that I have written there.
    Ok enough crap here on my part. You have waited (and read) enough. Here is the go...

    A skybox is a simple thing to create. All you need is a "room" (which as I said, can be a box, and sphere, whatever) as long as it does not have any holes in it. When you have made you sky to look like whatever you want, click on the class browser and then open the zoneinfo menu (click on the little + sign next to it). Choose Skybox info and then place that into the skybox, by right clicking in the 3D view and selecting it from the drop menu.

    When the zoneinfo is in the skybox itself, all you have to do, is to open the "advanced properties" of a texture, and then highlight the "fake backdrop" option. This will not appear to do much at all. It will only work in the actual game, or when you test it out from within the editor.


By

 Skybox Solution

By: Eradicator
monre@yebo.co.za

Foreword:

Skyboxes? Great stuff, right? But what if you see your redeemer explode against the moon? Yeah, not so great… Like the other tutorial I submitted before, the method I developed may not be the best, but still, if it is quick and easy to use, why not?

Abstract:

I have entered into a few forum sites and couldn’t find a way to deal with this, and when I finally managed to get something on it, I didn’t understand it. Maybe I was just still too rookie, who knows? But this is how I figured it out.

Assumptions:

You read Tomasz’s Skybox tutorial, and have built a skybox, but now experience the problem of “shootin’ da sky”!

Tutorial:

Intro

I won’t be taking you step by step to do it, but instead I’ll tell you how it is done, so that you can go and do it! It will be so easy that it will actually be pointless for me to sit and take shots of everything as I go along. In anyway, this tutorial is not about building the skybox, it is about fixing the problem with shooting the sky.

Tutorial

When you have your window looking out to the stars from the spaceship, or your clouds panning across the sky above, and find you shoot into the skybox and hit something, do this:

1.) Between you and the fake backdrop, build a thin wall/ceiling with the builder brush (i.e. a wall between the window to the stars and the fake backdrop outside.)
2.) Add the brush with the “add special” button, choose “regular brush” from the predefined settings, but tick the non-solid attribute before adding it in.
3.) Now click on the texture of the new wall and set its effect to be the new fake backdrop.

The effect

If you rebuild and test the map, you’ll see that you can safely shoot at the sky and not see the projectile hitting anything. This is simply because the non-solid attribute allows you to and everything else, to pass right through the brush, while still obscuring the view of anything behind it. The projectile effectively explodes, or whatever the case may be, on the wall behind the fake backdrop, completely out of view!


Wolf's Tutorial SkyBoxes

Wolf's Tutorials: Sky Boxes

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Skybox

To make those cool skies in Unreal you have to learn to make a sky box. A sky box is merely a "room" where you make your sky/outdoor area and then a ZoneInfo that acts as a sort of camera and is displayed on ceilings/walls that you set to "fake backdrop." Think of the SkyZone area as the "Stage" and the walls you set to display it the monitor (kind of). So, there are basically 2 components need. A skybox, and a surface set to "display" it.

Basics

To start with load the GenEarth textures. Now make a room 512 x 512 x 512. Give the ground a nice ground texture and don't worry about the walls, yet. Add a PlayerStart to this room wherever you want. Secondly, make another room the same size off to the side, away from the room you just built. This room will be the SkyBox.

Inside this room make a box 256 x 256 x 128 "box" in the middle of the floor.

Now load the SkyBox textures. In your skybox select any wall and press SHITF-B to select the whole brush. Change the texture to the cloudy one at the bottom. Now select the whole "box" we added to the middle of the room and change it's texture to the ground (GRD) texture. Your skybox should look like this now:

If you look at the textures in the skybox package (the ones like LND1 LND2 etc...) you will notice they look like mountains but with a black background. These are masked walls that will be the sides of our sky box. First, make sure no textures are selected and then right click the sheet tool to bring up the sheet properties. Set the properties to X wall, U:256 V:128 like below:

Build the sheet then choose one of the LND textures (I used LND2_1) making sure no other surface is selected. Position the sheet like below:

Now, select the "Add Special" tool and open it's properties. Set the properties to Masked Wall and make sure Masked, 2-sided and Semi-Solid are selected. Click the Add Special button.

Now rotate the sheet 90 degrees and move it to the next position clockwise. Select the next texture (LND2_1b).

Add special again, and then rotate the sheet again and choose the next texture and add. Keep doing this until you have all four "walls" added around the "box" we set in the center.

Now we need to add SkyZoneInfo to the box. In the Browser go to classes, info, zoneinfo and click on SkyZoneInfo. The zoneinfo will act as the camera so the "displayed" sky will be from the perspective of this zoneinfo as though it were the "camera." Place it as shown below:

Now we need to add a sheet brush the same size as the sky box, so select sheet properties and set the size to U:512 V:512 and select Floor. Place this sheet just above the masked walls we added in the center of the box:

Choose the cloud texture and add a masked wall. If you right-click the cloud sheet and select u-pan or v-pan effect, the clouds will move.

Now we need to add lights. This sky zone is small so we can just add one light, near the ground and keep the default settings.

Now, move back to our first room. Now we need to set the second component to make the skybox work. Select every surface EXCEPT the floor and right click to bring up texture properties. Choose Unlit and FakeBackdrop.

Now add a light to this room, rebuild and test run the map. You just built your first skybox!

Tips

You might have noticed first off that there was a visible line between the cloud sheet and the walls of the sky box. you would fix this by making the skybox room and cloud sheet larger so that the cloud sheet stretches well past the SkyZone info and the edges are hidden behind the mountain walls in the sky box.

Also, the panning speed of the clouds is kind of fast. You can control this speed in the SkyBoxInfo under ZoneLight, by changing the TexUpanSpeed and TexVpanSpeed. The smaller the number the slower it pans. Try .5 or .3 for a good speed.

You can also set the ambient light of the SkyZone here. This won't affect the lighting in the "world" just how bright the sky and everything in the SkyZone appear.

You can also add other sheet brushes, with planets or moons on them. Just set them below the cloud sheet and make sure masked and transparent are set. Note: You can not have double transparencies (that is one transparent sheet over another in a sky box).

You can also set the light colors, but never give them dynamic properties or corona's (len's flares) as this will slow the map down considerably!

Homework

See if you can duplicate this screen shot.

Play around with different things in the sky box (lighting, texture panning, etc...) and see what you can come up with. You should have the knowledge to build some really cool skies now.

Notes:

In the Unreal Levels you will often notice two sky boxes. You can only have ONE sky box per level. They used two sky boxes in Unreal because they had one for hi-resolution and one for low-resolution.

Never use dynamic light effects in sky boxes. You can use non-solid sheets in the skybox instead of semi-solid sheets.

If I left anything out of this tutorial or if you aren't clear on something or just have questions about it, please e-mail me and I will answer your questions. Have fun!

-Wolf

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


HOW TO CREATE SKYBOXES…

By: Sliencer

utcity@planetunreal.com

UT City

FOREWORD:

I am suspecting that you know how to Create a basic level, using lights, Rotating brushes, and knowing the basic buttons, and are familiar with the sheet properties. Download Tutorial Map

DIRECTIONS:

Right now we’re going to create a simple but quality skybox. Look below to see it:

2-4

Start out by opening or creating a level. Next open the texture set titled: ShaneSky.utx. There are other texture sets for skyboxes but for now I’m going to use this one. Now, off to the side somewhere, so that’s it’s not touching anything create a 1024x1024x1024 cube. Use the STARS texture and add it to your world. Now create a 256 length, 256 width, and 128 height cube. Move it to the bottom center of your skybox cube and select the PANTILEB texture and subtract it. The add a light on the top of that cube and if you want press the F8 key and rebuild geometry to see what it looks like. Next click on the sheet button and right click on it and go into sheet properties. In sheet properties choose the Y-Wall orientation and under Size put: U:256, V:128, then click build. Now align the brush so that it is on the side of the box and is on top. Refer to figure 2-4a:

2-4a

If it your screen looks the same then continue otherwise repeat the above process and try again. Now click on the Add Special Brush button (Big green one with dotted lined square in it.). We want to build a Masked Wall so go ahead and select that from the Predefined options. Now under Masking choose Masked, under Visibility choose 2-Sided, under effects make sure nothing is checked, and under Solidity choose Semi-solid. Then click on the PANTILE1 texture and select Add Special. You should notice something like this:

2-4b

Note: PANTILE1 and PANTILE4 seem to line up well when creating skyboxes so I recommend using that pair. Now either rotate the sheet or go back to sheet properties and choose X-Wall. Repeat this process all the way around until you get to something like this:

2-4c

(Note: Sometimes you won’t be able to see the masked wall at first. So to see it press the F8 key and rebuild geometry. If you still cannot see the masked wall then try again and make sure that it is 2 sided. Also if you notice that the textures aren’t aligning correctly try rotating the object and adding a special brush again and/or try selecting the masked wall and changing textures. Once aligned they should look alike like the above image.) Now that the hard part is over with all you have to do is go into Classes and click on the minus sign next to *Info, then the minus sign next to *Zoneinfo, then select *SkyZoneInfo (not the minus sign). Then right click in the middle of your skybox in your 3D view and select Add SkyZoneInfo here. Finally go back to textures, select STARS again, and create a sheet with the following properties: Ceiling/Floor orientation, U:1024, V:1024. Then click on Build. Now align the Sheet to be centered on top of the skybox and just 16 – 32 units higher than the masked walls. It should look like this:

2-4d

If I does then click on Add Special Brush and create another masked wall the same way you’ve done before. Now you should see a semi see through set of stars. Good. Now go back to your level part and select any walls/ceilings that you want your to view your skybox as a background. Right click on the selected texture(s) and go to Surface Properties. Now under the Effects tab select Unlit and Fake Backdrop. The close it and rebuild geomoetry and check out your cool spacelike skybox!

----------------------------------------------------------

ADDING OTHER EFFECTS TO YOUR SKYBOX…

So you want to add more stuff to your skybox eh? Well below are some of the effects you can add:

-Planets
-Lightning
-Rain
-Movement (Like in Facing Worlds)

(Note: These are only the effects that I know of, there may be more.)

Adding Planets is fairly simple, all you have to do is create a sheet that is aligned with the floor and ceiling at about 128x128 – 256x256 units and make it masked and double sided and you’ve got a planet. Just put it below your larger set of stars under your 1024x1024 STAR sheet and you’ve got a planet. (Note: Planet textures vary in size which is why I said 128x128 – 256x256 units because these are the average sizes.) As for lightning, rain, and movement, I’ll have to cover those in a future tutorial.

CONCLUSION:

You should now know how to make a regular skybox. Try using different texture sets such as Skybox.utx and make some different textures skyboxes to fit your maps atmosphere. Also another trick is making all the masked wall on the floor of the original 1024x1024x1024 without putting them on top of the 128x256x256. For more information on this download one of my maps: DM-Sanddunes or CTF-BunkerCommand and see the skybox for yourself.

OTHER:

Comments/Questions Email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


SKYBOXES

by ATF_Deftek

OVERVIEW

So you wanna make a skybox...

FORWARD

This is the first tutorial submitted by ATF_Deftek

CONTENT

When I first learned about skyboxs, I thought they were huge. I built my first maps like this: 10000 by 10000 by 10000. I thought that the walls would be the skyboxs. How wrong I was. Skyboxs are very tiny. To make a Skybox follow these steps: First make a room 256 by 256 by 256. We will call this room: Room 1. Look through your texture browser and select a sky texture(there are some good ones in Skybox.utx). Go ahead and apply the texture to the walls as you see fit. Put a texture on the ceiling as well. Forget about the floor. Now make your level(normaly you SHOULD make your level first). Make a room 256 by 256 by 256. We will call this room: Room 2. Texture it as good as you like. Now make a brush 32 high, 192 wide and 192 long. Put this in the exact middle of Room 2 and then raise it up so the bottom of the brush is on the same level as the roof. Subtract. Put textures on the sides of this new "roof" but not on the very top. Now, this a very important step. Go back to Room 1 where your sky textures are. Select all the walls and right click. Select "Surface Properties" and under "Flags" click on "Unlit". This a very important step. Now click on your actor browser. Click on "Info" and then "Zoneinfo". Now click on "Skyzone Info". In the 3D view right click on the floor. Select "Add SkyZoneInfo here". Using the top down view, move the SkyZoneInfo to the middle of Room 1. Your skybox is done. But you can't see it in your level yet. Go back to Room 2 and select the roof(the one in the middle you didn't texture. Right click on it and select "Fake Backdrop". Now put a player start in room 2 as well as a few lights but not on the area you selected as "Fake Backdrop". Now "rebuild all" and play the level. Look up and walk around. You just made a skybox!

ABOUT

Tutorial submitted by ATF_Deftek


How to build a basic Skybox

By: Infinity

INF_IN_ITY@yahoo.com.au

UT Newbie Mappers Guild

This is a brief tutorial that will cover all of the necessary steps required to construct a fully functional skybox. Skyboxes are really quite basic, a skybox is built apart from the main play area of your map, quite simply we make our skybox to look like sky, then we stick a camera (skyzone info) in there, the images the camera (skyzone info) captures are then projected onto all of the surfaces we set to fake backdrop, acting like a tv screen. Well that’s the basic idea, so lets get started.

Note

This tutorial will cover the application of two types of arenas; one is an indoor area, the other an outdoor area. Also the tutorial will be written on the assumption that you know the basic building principles of Ued 2, i.e. you know how to add subtract intersect de’intersect and apply and align textures and so on. I hope you find this tutorial of use, I’m happy to hear all and any comments you may have in regards to the information I have supplied. If you would like to contact me, I can be found hanging at the UT Newbie Mappers Guild forum, or you can simply e-mail me. Thanx.

Build a room

Step 1:

Ok, first things first, build a cube brush to the desired size and subtract it to form a room, (mine is H/512 x W/1024 x B/1024) this room will be known as room1. Go ahead and texture room1 now if you like I’ll leave that sort of thing up to you.

In order to see the sky from room1 we will need a window or opening in the ceiling, to make this window however we first need to build another cube brush but this time we will make it smaller, say (H/128 x W/512 x B/512) this room we will call the skybox.

Build the brush and maneuver it so that it is in the exact center of room1, then raise it up so that it is say 32 units above room1. Once you have the skybox brush in position subtract it.

Now here’s the important bit, select all the surfaces in the skybox (the floor is not that important) then right click on any one of the surfaces to open the popup menu, select surface properties, select the ‘Flags’ tab, then check ‘Fake backdrop’ and ‘unlit’ this is very important, if you want you can texture these surfaces but its not totally necessary.

Ok, now we can put our opening in (or take it out, whatever), build

another cube brush this time make it (H/34 x W/256 x B/256) and maneuver it so that it is in the exact center of room1 again and position it so it is between room1 and the skybox as seen in the pic above left (sorry bout the pic quality). Intersect it subtract it and texture the sides.

By now you should have something like this, a textured room with a hole in the ceiling looking into a box above of which all surfaces are set to ‘fake backdrop’ and ‘unlit’, disregard the textures they may not be the same as mine, but that’s not important.

Ok now that you have your room to this stage, feel free to add as much detail as you like, i.e. beams lights etc.

Build a Skyzone

Step 2:

All right, now that room1 is ready for a sky, let’s set about creating one; first build a cube brush (for the purpose of this exercise I’ve made it the same size as room1,) this room will be known as the Skyzone. Now move the Skyzone brush away from room1, and subtract it.

Note

When you build a (skyzone) it is important that you place it a good distance away from the main play area of the map, this will insure that it wont get in the way. As it doesn’t need to be in contact with your map, you can place it as far away as you like, unless your map is finished and the (skyzone) is the only thing left to build in this case it can be placed anywhere, but be sure it doesn’t come into contact with your map. (I hope that makes sense).

Ok, once you have found a good spot and subtracted your skyzone you now need to add texture, find a good sky texture (I have used one from ‘City.utx’) and apply it to all surfaces in your skyzone, in this example the floor is not important as it will not be seen.

When you have the desired texture applied to the walls and ceiling build a cube brush (H/128 x W/256 x B/256) and maneuver it into the center of the skyzone, move it down so that it is on or near the floor of the skyzone and add it and texture it.

Note

This will be the ground that you will see, if the ground is to be visible from your map. In this case the ground will not be visible, as this tutorial map will be set in a high rise building in the city. So it’s a good habit to choose your textures carefully to insure it looks good in your map! (Even if it won’t be seen).

Ok, by now you should have something like the pic above disregarding textures of course.

Now we need to add a background so that we are not looking at only sky, this tutorial map is supposed to be in the city, so I want buildings in the background. To do this we need to add 4 masked walls, so right click on the sheet tool, and build a sheet (H/256 x W/256) maneuver it so that it is sitting flush on the edge of your ground brush as seen in the pic on the right.

Now an important step; on

the tool bar to the left, go down to the ‘add special brush’ button this will bring up the dialog box shown on the left, in the prefabs dialog bring up ‘Masked wall’ as shown and click ok

Note

The reason (I say) this is an important step, is by simply adding a sheet, all you are doing is adding a surface. This is bad, as you cannot delete a surface that has no defined brush supporting it. However if you add a sheet with the ‘Add special brush’ tool, it will be added with a defined brush, this is good for if you ever need to delete it you can! (I learned this the hard way).

Ok, repeat this step until you have a masked wall on all 4 sides of the ground brush.

Once this is done, open the texture browser and select a suitable texture for a masked wall i.e. Choose a texture that looks like mountains buildings or whatever you like, there are some good mountains in the ‘skybox.utx’ package, also there are good buildings in the ‘City.utx’ package, this is the package I have chosen to use for this tutorial.

Now apply the desired textures and align them accordingly, you will see that part of the texture is invisible so you can see the sky behind it, as you can see in the pic on the right. So by now you should have something like the pic on the right.

Now we are ready to add our ‘Skyzone info’. The ‘Skyzone info’ will act like a camera that will send the images from the skyzone to the surfaces we earlier set as ‘Fake backdrop’ in the skybox above room1.

To do this simply open the ‘Actor class browser’ (see pic on left) open ‘info’ open ‘zoneinfo’ then double click ‘Skyzone info’, this will activate the ‘Skyzone info’ script, minimize the script window (if you have a small monitor like me).

Now in the skyzone right click on the ground in the middle of the 4 masked walls, and select ‘Add Skyzone info’ from the pop up menu.

Now position the ‘Skyzone info’ low to the ground and in the exact middle of the ground but not too low! See the pic on the right.

That’s it, you now have a functioning skybox, go to room1 look at the hole in the ceiling, now activate real time preview, and you should see your sky being projected onto your ‘fake backdrops’. However it is lacking detail, this needs to be rectified, so that’s the next step. Well by now you should have something like you see in the pic on the right.

Add some detail

Step 3:

This is the point at which we add lighting, and props like moons flairs and cloud layers etc. The detail you add here is extremely important to the look of your map, as it is now a major part of your map. The amount of detail you add is entirely up to you, however I will give you a brief run down of some of the seemingly endless possibilities there are to explore.

First I want to break up the sky a little, it’s a bit monotonous and it lacks depth, so I am going to add a layer of cloud. There are a number of different effects you can use to make a convincing cloud layer,

I’ve chosen quite a simple yet effective way for the task at hand.

Simply build a sheet roughly the same size as the skyzone, lay it horizontally above the masked walls in the skyzone, and bring it down close to the top of the walls. Now choose a good cloud texture and then click on the ‘add special brush’ tool, now check; ‘masked’ ‘transparent’ and ‘2 sided’, set it to ‘non solid’ and add it.

Now you should have a transparent cloud layer floating above the tops of your masked walls. You can set the cloud to pan across the sky, simply by right clicking on the surface and bringing up the ‘surface properties’ dialog box, click on the ‘Flags’ tab, and well, have a play around with the panning, also click the alignment tab and play around with the scale and alignment, until you find the combo that best suits you! You can also set the other surfaces in the skyzone to pan, this can help to add a little more depth to tour sky.

Note

The best way to learn what to do at this point is to experiment a bit, there are many ways to make a sky box look good, but there are just as many ways to make it look bad, the only way to find out is to do it, its your map so you have the best idea of what you want your sky to look like.

You can add sheets to apply moons, flairs, clouds etc. Where and how you place them is entirely up to you, so once you have your skybox up and running, mess around a bit and see what if any limits your imagination has.

Lighting also plays a major part in the success of your skybox; this is where you can really let the creativity flow, experiment with different colors, use the special lit feature to light specific areas without interfering with others, and so on. As I said, seemingly endless possibilities. However keep in mind that dynamic lighting effects will not work in the skyzone.

Here are a couple of examples of some slightly different skyzone setups, note the cloud layer in the first shot is denser than in the other two shots. In the first shot the cloud layer is set to ‘masked’ only, where as the second shot is set to ‘masked’ and ‘transparent’, and the third shot is set to ‘transparent only. Also note the lighting, a city sky line at night is filled with different colored lights, so I have tried to reflect those colors onto my cloud layer, this also helps to add depth. So experiment and have fun.

Add an outdoor area

Step 4: Optional, this section is simply to show that you can make additional areas even after your skybox is complete.

Now I will show you how to activate your skybox in a simple outdoor area, in this area you will get an optimal view of your creatively engineered skybox.

Build another room (H/512 x W/1024 x B/1024) we’ll call it room2. Now build a cube brush half the height but the same width and breadth of room2 set it to ‘hollow true’ and make the wall thickness 16, move it to the bottom of room2 and center it with room2.

Now de’intersect it and add it, now room2 is divided into two halves, one on top, one below.

Build another cube brush, this time make it (H/32 x W/1008 x B/1008) set it back to hollow false, move it up so that it will cut through the top of the hollow brush you just added, intersect it and subtract it. Now you should have a room that looks something like the one in the pic above to the right. You can connect room1 and room2 together if you like.

Ok simply select the surfaces in the top half of room2, right click on one of them select ‘surface properties’ click the ‘Flags’ tab and check ‘fake backdrop’ and ‘unlit’, hit the real time preview button, now you have a simple outdoor area see pic on right.

The rest is up to you now, you can light the out door area to reflect the atmosphere of the sky

To make it more realistic, and add all the detail you want.

Note

This tutorial has outlined the procedure to build a basic skybox; there are many ways to build a skybox from the very simple to the very advanced. I suggest you build something like this tutorial map to get a feel for what is involved, and also look at skyboxes in other maps, not to copy but to see the variety of ideas available. Once you have one skybox under your belt, you will have a better understanding of what is needed, and how to go about it. If you’re not totally satisfied with this tutorial, there are others out there that may give more detail on more advanced types of skyboxes. However I hope this tutorial is sufficient, and this type of skybox is quite quick and easy to set up. So practice a bit and you’ll be a master in no time.

So That’s it, you now know most of what’s involved in building a skybox, so good luck and have fun, don’t hesitate to get in touch with me if you want to, your comments are very important to me. I hope [image] you have learnt something of use. Thanx.

Disclosure

This tutorial is for the express use on the Utnewbie Mappers Guild website only, unless given permission by me, Ned Kelly© 2001. INFINITY logo © 2001.

I hope this tutorial is of use to you, however, it is based solely on my own knowledge, and may not be 100% accurate. All info given is done so in good faith. If you find any discrepancies, please let me know. Your input is welcome. All completed maps if less than 1.38 MB should be sent to utnewbies@inorbit.com where the members of the UT Newbie Mappers Guild will be waiting to help or review your map. Thanx!

INFINITY mailto: INF_IN_ITY@yahoo.com.au

UNREAL TOURNAMENT & UNREALED ___

Unreal Tournament & Unrealed ©1999 –2001 Epic Games Inc. Created by Epic Games Inc, in collaboration with Digital Extremes. Unreal and the Unreal logos are trademarks of Epic Games, Inc. All rights reserved. All other trademarks are the property of their respective companies. Copyright © 2000, © 2001 Infogrames Entertainment S.A. All rights reserved.

____


Unreal Editor Maximum [unrealism.com/unrealedmax] - A Standard SkyBox

SKYBOX TUTORIAL

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

WHAT THIS IS ALL ABOUT

There are a lot of tutorials on the web dealing with how to create a skybox and a ton more on this site. But for those of you who have read these tutorials and are still not able to make a good one I have included the complete measurements that I have used for getting a good skybox. Admittedly this will stifle the process of creative thinking. But hopefully at the end of it you will be better off than when you started the tutorial.

HOW DO THEY GET THOSE GREAT SKYBOXES?

Here are the exact steps that I followed in creating a skybox:

1. Load genfluid, shanesky, shaneday and skybox by hitting the load button under the texture menu on the right. They have all the cool sky textures that you will need to create a a nice sky.

2. Choose a nice sky texture from genfluid. Build a cube 256x2304x2304 by editing the properties of the cube. With that done hit the subtract button (second button on the third column) or ctrl+s. This will be referred to as the first box for the rest of the tutorial.

3. Choose the DBottm texture from shaneday and apply it to the floor of this box.

4. Build a smaller cube 128x576x576 and using the side view place it below the first large cube that we made. Now in the overhead view center it exactly so that its in the middle of the box. Choose the GRD texture from skybox and subtract it. Your box should look like this now.

5. We are going to use the sheet builder to create mountains within the second box. You need to do this so that in outdoor levels it'll look like your map is in the middle of a mountain. Build a sheet with orientation set to X or Y wall, and size U=256 and V=256. I turned the gird down to 16 units and in the overhead view I placed it two units away from the second box and in the side view I let the sheet touch the bottom. For now the texture of the sheet does not matter. Hit the add special button with the following checked:

6. See that the sheet that we added in is still selected (select it if it is not) - it will be pinkish in color. Use the overhead view for the rest of this step. Hit crtl+w exactly 7 times so that this brush is duplicated that many times. Still using the overhead view rotate each brush and place them in such a manner that they form another cube within the second cube that we subtracted. You should now have 2 added in brushes to the north, 2 to the east, 2 to the west and 2 to the south. Zoom in (turn the gird down if you have to) and check that all the edges of all the added in brushes are touching. The level should look like this in the overhead view now:

7. Load skybox if its not loaded yet, you should see some textures numbered sequentially like 2_1, 2_2, etc. This is used to give a continuous but yet dissimilar look to your mountains. Ok go to the first sheet in the 3d view and apply texture 2_1, the next one 2_2 and so on. If all is not sufficient you can still use the same textures. Also the similar looking mountains all have the same starting number so you will be well advised to use the same group throughout your skybox. Select all 8 mountain surfaces by holding ctrl and left clicking on each. Go to their surface properties - F5 - and under the scale tab in custom scaling enter 1 for texture u and 2 for texture v. Hit the apply button. It should look like this now:

8. Build a sheet 2304x2304 floor/ceiling orientation. This is going to be the sky. Place it so that it fits over the first large box exactly in the overhead view. Move the sheet so that its just a few units below the top of the first box. Hit the add special button, choose regular brush from the drop down menu and make sure that regular, 2-sided and semisolid is checked under the various options. Go to the surface property of the sky that we just now added and check u-pan under the effects tab. This makes it look like the clouds are rolling across the sky.

9. Now for the sun (could be a moon or nebula or what you want but for now we'll just add in this). Choose flare10 from shaneday. Build a sheet 128x128. Place it above the mountains but below the sky, place it near the mountains and do some rotation so that its faces inwards towards the mountain. Hit the add special button, choose regular brush from the drop down menu check that 2-sided and transparent (under effects) is checked and hit add special. You should have a nice sun in your skybox. Do a crtl+w of the sun and place it at the other side and in a few other places. This is the way to add in moons, nebulas, etc. I almost always set their surface properties to unlit as they look quite ugly otherwise. This is how it should look like now:

10. This is the most interesting part. I expect you to have read a colored lighting tutorial. The lighting that you apply to the sky will determine how dramatic it will be in the when it appears in the level. I used a total of 7 pairs of lights - I placed them just beneath the sky with all the pairs scattered over the skybox. All the lights had their properties with light brightness set to 64 and light saturation to 100. The only value of difference is of course the light hue. These are the values that I used - blue 175; green 134; red 0; pink 18;etc.

11. From the pull down menu on the right choose classes. Expand info, zone info and select skyzoneinfo without expanding it and add it into your skybox (right click in the center of the mountains box and hit add skyzoneinfo here, if you were to place it anywhere else it would look cock-eyed). This tells UT that this is a skybox and has to appear in your level.

12. Build a cube 1024x2048x2048 choose a nice rock texture from genearth and subtract it. Set the surface property of the ceiling of the room to fake backdrop so that your skybox shows up in the level. You could go ahead and add lights to the rest of the room but since this is a tutorial just select all the remaining five surfaces and check unlit in their surface properties. Add in a player start from under navigation point in classes. Rebuild geometry and lighting. Fire it up in unreal tournament and it should look like this:

GENERAL SKYBOX NOTES

  • Now that you've checked it out in your level and found that it rocks you need to save it. Build a larger brush than the skybox and hit the deintersect button or ctrl+d. Go to the brush export menu and give it a name and hit save. Now whenever you have a level and need a standard looking skybox just hit import brush find where you saved it and open it up - leave the merge coplanar polygons checked in the import brush dialog.

  • You can use just red or orange lighting in your skybox and check out the effect. The lighting is a very important part of the skybox - I would say most important as it is the lighting that makes a level stand out.

  • You remember in step 8 where we made the clouds look like they were rolling across the sky? Here is a tip that most people seem to ignore. The speed at which the clouds roll across may be fine but what if you want them to move faster?. Simple expand the sky zone infos properties and expand zone light. Here you will see two fields called TextureUPanSpeed and TextureVPanSpeed, you need to alter one of these values. Since in step 8 we made the clouds go in the u-pan direction set upan speed to around 4, hit the little joystick button in the 3d view so that it is unchecked (this turns on real time) and see how fast the clouds roll across. Remember this property can be used in any zone info actor.

  • One cool way in which to achieve the effect of a night sky is to give the ceiling of the skybox (the first box) a night texture from genfluid, set its surface property to unlit and set the surface property of the sky to transparent. It will look like this in the level:

  • In step 8 when I asked you to set the u-pan speed to make it seem that the clouds are rolling across the sky, you will notice that the clouds move across at a default speed. To make the texture pan slower or faster go to the sky zone info's properties and under ZoneLight you will find two entries called TexUPanSpeed and TexVPanSpeed. Now if you want the texture to "scroll" across faster set the UPanSpeed to a higher value and if you want the texture to scroll across slower just lower the value. You'll find that the clouds will move across faster - try a value of 10. One thing to note you can use this in any zone infos not just in the sky zone info.

  • I usually end up building the whole skybox out of non-solid brushes as this can conserve resources.

  • As I said before don't confine yourself creatively to standard skyboxes. Levels that really stand out and are appreciated will have some surprising effects used in their skyboxes like Facing Worlds. Like the Bon Jovi song "its just the same old sites and the same old sound ........ the same old shit is going around" - don't do that.

LIST OF SKYBOX TEXTURES

In no particular order below is a list of .utx texture packages that contain textures that you can use in your SkyBox. Note: This list is not meant to be comprehensive.

  1. castle1.utx

  2. city.utx - If you build any city kinda levels you'll find everything for your sky box here.

  3. DDayFx.utx - The AS-Overlord skybox textures.

  4. EgyptPan.utx - For an Egyptian SkyBox full of pyramids.

  5. eol.utx - Just one moon texture.

  6. FractalFX.utx

  7. genfluid.utx (sub-class sky) - The base package that contains the most amount of sky type textures that you can use in your level.

  8. GenFx.utx (subclass lensflar)- This texture package contains flares (which can be used as suns).

  9. GenTerra.utx

  10. Genwarp.utx

  11. Hubeffects.utx - Nice lightning textures.

  12. Indus1.utx (subclass skybox) - Nice misty textures and some general ones.

  13. Indus3.utx

  14. Indus6.utx (subclass sky1) - DM-KGalleon skybox.

  15. JWSky.utx - Contains some great haze textures. Also has the SkyCity textures.

  16. NaliFX.utx

  17. ShaneChurch.utx - Two moons.

  18. ShaneDay.utx - Snowy mountains textures. Also contains the two textures DaySkyB and DBottm that are used as a sky box base in many, many levels.

  19. ShaneSky.utx

  20. SkyBox.utx - Need I say more? :).

  21. SpaceFX - Contains the best nebula textures and the earth sky box textures (one 512x512 texture and 4 textures to build huge sky boxes with the earth in it).

  22. XbpFX - These are the "Innox textures". Used by Innox to make the CTF-Face and DM-Phobos levels skyboxes. Contains the mars textures, earth textures, a few nebulas and a night sky texture.

  23. XFX.utx - Has an extremely cool lightning texture and some other effects.


BB Drac - Unreal Tournament UED2 guide Zone, Skyzone

Skyzones

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

When creating a skyzone you actually create a "room" that is not connected
with the rest of the level.

So start by creating a room (256x256x256) and apply textures as you feel.
Also add a lightsource.

Now create a small brush 32 height and 192x192.
Place this ontop of the room and subract it.

Screenshot

When that is done and you have added the textures you want,
create a brush 256x256x256.

This brush must be subtracted outside our original level.
Load the texture set "egyptpan.utx" and apply "SkyBPyramidTop"
to the roof and any of the "SkyBPyramidD#" to the walls.
(Don't mind the floor.)

Screenshot

This will be the actuall skyzone.
(Note that a skyzone can be in any shape and size).

Each of the sides inside this skyzone must also be checked "Unlit".
Otherwise we must spend time to make the lighting correct and that might
need some time.
To check the "Unlit" option you must enter the properties for each side, roof
and floor.

Open the actor browser.
Select "SkyZoneInfo" under "Info" and "ZoneInfo".
Add this actor inside our skyzone "room".
Place it in the middle.

Screenshot

There is only one thing left to do.
That is to change a flag for the roof texture in our first room.
Open the surface properties and in the "Flag" tab you check the
"Fake Backdrop" option.

Screenshot

This will tell the engine that this wall should now work as a viewport through
our "SkyZoneInfo" actor.
It is therfore important to make sure that you place this "SkyZoneInfo" actor
where you want the view to come from (as a source).

Add a playerstart and rebuild the level to see the skyzone in action.

Screenshot

Rotating sky:
To create a rotating sky you should first understand that it is not.
the skyzone that rotates but the skyzone actor.
The skyzone actor works as a camera for the fake backdrops and
when the camera rotates it will give the feel that they sky is rotating.

The properties you need to adjust is found in the skyzone actor.
Under "+Advanced" you must make sure that "bStatic" is false.
Under "+Movement" "bFixedRotation" must be true and "Physics" is
set to "PHYS_Rotating".
To change the rotation rate and speed, modify the "Pitch", "Yaw" and
"Roll" properties under "RotationRate".

 Decorating the skyzone:
Everything you place in the skyzone will appear as parts of the sky
when playing.
If you create clouds you can create a large sheet that is placed
close to the top and make it transparent and masked.
Modify the U/V pan direction and speed and you have a nice set
of clouds moving across the sky.

Create another sheet with clouds if you want your sky to have
a more depth feel.

By adjusting the lighting of a lightsource in the skyzone you can make
the clouds have different colors and in different areas to give the
feel of sun- set/rise and other space phenomena.

A sun, moon or any texture that is masked will look best in a skyzone if
you do not have it masked but instead check the flag "Transparent".
The (masked) dark area around the object will more or less disappear.
It do not look good in the editor but do in the game.
(Sometimes this may not be the case, check both options).

The best way is to play around with the skyzone and see what looks good and not.


BB Drac - Unreal Tournament UED2 guide Advanced Skyzone, Lightning

Skyzone Lightning

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Think that your current skyzone is flat and lifeless?
What about adding lightning and thunder?

This is how to do it the simple way.

To be able to follow and understand this tutorial it is important that
you understand zones, movers and triggers.

First you need a basic level with a functional skyzone.
In this level I have created a "castle" entrance with a high up in the mountains
look and a river with some haze.
The skyzone have two layers of clouds and a few lights with different light
colors to give a more 'colorful' look.
Also four sheets with distant mountain look to both give the high up in the mountain
feel and also to prevent players from seeing the walls.

How you really do this is not important but in this example it looks good but
is still very basic.

Screenshot

To actually create the lightning we need a mover as it should not be visible
unless it is 'lightning'.
This screenshot show all that is needed.

Screenshot

What you see is a light, mover, dispatcher, stochastic trigger and special event.

Lets mix all this together.
First the mover. The mover is really a volumetric sheet (or two sheets crossing each other) with a
texture that do not look like a real lightning but have to do for this example.
(All sides of the mover is unlit to prevent lighting problems).

The mover is in its first keyframe (keyframe 0) outside the actual skyzone but
inside in its second keyframe (keyframe 1).
The second position is right under the light you see from the screenshot.
Reason for this is that when the lighting starts we want the sky to light
up a bit.
That is why the light is a triggered light.

The dispatcher is used to first activate the mover, which have zero seconds
move time, and then trigger the light.
The mover have 'stay open timed' so it will disappear after the specific time
which is the same delay the dispatcher have before it triggers the light again
to turn it off.
To activate the dispatcher at random intervals we need a stochastic trigger
set with a few values to create random outcomes.

This is not all.
With lightning we need sound.
This is what the special event do.
It will play a thunder sound effect for all players when it is triggered.
The special event is triggered by the dispatcher right after the lightning to give
the slight delay to make it sound more realistic as light travel faster than sound.

This is how it works:
The stochastic trigger will trigger the dispatcher at random times.
The dispatcher will trigger the lightning mover and the overhead sky light.
The mover will return by itself while the dispatcher triggers the light again
to turn it off and also triggers the special event which plays a thunder sound
effect for all players.

In the downloadable version of this map I have made the lightning happen far
too often.
It is just for show and not for realism.
And the design is pretty flawed and need some adjustments but could work
out nice.


deCyber Build Section

SkyZones

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Downloadable files : SkyZone.UNR

Contents

1) Create your_sky area
2) Create a viewing area
3) Improving your skybox

Introduction

A nice scenic sky is probably one of the things that really gives your level an impressive feel, and UT does this particularly well. If you’ve never done this sort of thing before, creating a sky view can be confusing business
(it confused my brain off when I first tried to get to grips with it).

All of your sky and distant landscapes are created in a separate box all on their own. Inside this box you have a "SkyZoneInfo" item which acts as a sort of video camera. The TV screens that show what your camera sees will be the walls of the rooms in your level. If that is still confusing, don’t worry, as you start to make one yourself, it will gradually become clear what’s happening.

Again, this is just the way I did this, and there may be better ways of doing this, but I found that this worked for me.

Create your Sky area

1) The sky area you build needs to be quite a bit larger than the area in your map you want to see it from, but it shouldn’t be very high. Create a box 2048 x 2048 wide and 512 high. Choose an earthy type of texture for your ground (use GENearth.UTX), and pick a sky texture from GENfluid for the other sides of your box

2) Now you need to add some light for your sky. Place one light actor as close to the center of the box as you can and adjust its settings to suit your taste. This is a large area, so you will probably need to enlarge your light’s radius to cover a larger area of the sky. Or you could add an extra light which you could have a different color. Rebuild and save your level. Try and avoid having any of the sides of your box lit up as this doesn’t look to good in your map when you play it.You’ll have to experiment and fiddle to get a result you like.

See the tutorial on LIGHTING if you’re unsure.

3) Now you need to put your "video camera" in there. Open the "ActorClassBrowser" and choose "Info" then "ZoneInfo" and under that class you will find a "SkyZoneInfo". Add this item to your Skybox, and your Skybox is now ready. All you need now is somewhere to view it from.

Create a viewing area

4) Create a room 512 x 512 x 512 and in the usual way, add a light, a player start and set your game type to something like SinglePlayer so that you can actually run around in there. Rebuild and save once again.

5) Now you need to tell this room that the walls are actually the sky. Select every side of your room apart from the floor. (Keep the control button pressed as you select each surface and they should all highlight. Or you could click one of them, then press SHIFT-B and de-select the floor). Now press F5 and you should see the surface properties box appear. Make sure it is on the "Effects" tab. One of the fields is called "fake backdrop", click on that one so that a tick appears. All of your walls and the ceiling will now act as giant TV screens for your Skybox area.
Rebuild and Save, then try it out. You should be walking around on square platform which appears to be hanging high in the air with the sky all around you.

Improving your skybox

That was an extremely basic skybox just to show you the principle, but there is much more you can do to make it look more impressive. Try the following suggestions.

Scale:
Because your Skybox is a large area, you will probably need to adjust the scale of the textures in your box. Click on one of the sides so that it is highlighted, press SHIFT-B and then all the sides of your box should be highlighted. Now press F5 to bring up the properties of each sheet (it should say 6 selected at the top). You need to click on the tab that says "Scale". In the field that says "Simple Scaling" click on the drop down menu and choose 2 or 4 (whichever you like), click on"apply" and then close it. You should see your textures appearing a lot larger now.

Moving Sky:
Why have a static sky when it's easy to make it move? To do this, just click on the sky textures within your skybox and press F5 to bring up their properties. Click the field called "U-pan" and this will cause your sky to move. "V-pan" also does the same thing but along a different axis. You may find that when you run your level after changing this that the sky is moving too fast. If this is the case (or you want it slower or faster anyway) then click on the "SkyZoneInfo" actor and press F4 to bring up its property box. There is a property called "ZoneLight".
click on that and reduce the"TextUPanSpeed" (or V if used that one) to 0.5 instead of 1 and that will slow it down.

Mountains:
Unreal provides textures that are perfectly designed for this purpose. Choose the texture pack called "Skybox.UTX" and you’ll see some textures that look like a mountain range. You will be using these. (There are similar mountain textures in other files too).

Set up a sheet 256 wide by 128 high (both the ZONES tutorial and TELEPORTERS tutorial will give you more insight into making sheets). Place it so that it comes up about half way through the bottom of your skybox, fairly near the centre. Now add 8 sheets next to each other to form a large square around your SkyZoneInfo actor.

The left-hand picture is the top view and the picture above is the side view. Each of the 8 sheets should be another mountain texture that follows on from the last, otherwise you will have very strange looking scenery! Set the surface properties to be "masked" (on the "effects" tab F5) too.

Adding Actors
You can also add decorations into your skybox, and if you position them correctly they’ll look quite good. If you look carefully at the sample map, you’ll see a Skaarj scoutship placed in the mountains. You can also add pawns like birds to circle in the sky too.

It all adds to the scenery, but don’t add to much, it may slow things down a little.

Swallowing Projectiles
Isn’t it annoying when you play a level that looks pretty good and then you shoot the sky and your ammo impacts on an invisible wall? Well there is a way around this. I was pointed in the direction of using a "CloudZone" actor to do this before, but never had any success with it. Instead, I found another way to do it.

Create a sheet the same width and depth as your room (the one with the playerstart in it). Add the sheet to your world using the "Add Special Brush" icon. In it's surface properties tick the "fake backdrop" field. Once you rebuilt and saved, play it and you should see your projectile get swallowed up when you fire up at the sky. You may still hear the sound of the impact if your ceiling is close, but at least you won’t see it!
Note: This still doesn't stop ripper projectiles from bouncing off though!

Clouds
To add to the realism, you can even add clouds. Just select a cloudy texture, and like you did in the "swallowing projectiles" exercise, add a sheet near the top of your skybox. This one should also have its "U-pan" clicked on and should also be transparent.

Stars and Moons
Again, there are other textures (Skybox and SpaceFX) that have textures of stars and moons. All you need to do is add these in to your skybox tilting inwards near the top as another small square sheet.

EZkeel
(Simon West-Bulford)


How to Make a Skyzone

By: astro

astro@planetunreal.com

UED Resource Lab

This tutorial will outline the basic steps involved in creating a sky zone for your level. I have created a quick level that will aid in the learning process. You should have some basic comprehension on level building with Unrealed before attempting this tutorial.

First let me go over sky zone (sky box) basics.

1) There is only ONE skybox per level. The Sky Box is what your sky is created in and what will be seen as the sky in the game. There can only be one sky box because only one SkyZoneInfo can be used per map. The sky box is made apart from the rest of the map and usually is not connected in any way with other parts of the map. That is where the SkyZoneInfo comes into play.

2) The SkyZoneInfo icon looks like this: This acts like a camera in your skybox. Change the position of the SkyZoneInfo and it will impact how your sky looks in the game.

I will now show you how to build and implement a Sky Zone / Sky Box.

Editor used: UnrealED2.0

Fire up good ol' UnrealED and create a room that is 512*1024*1024. Add some lights, a player start and rebuild. You should now have something that looks like this:

Next, create a room the same size off to the side that is the same size and decorate it with stars on every wall. In the texture browser open up the genfluid texture pack and select Ntskyt.

You can hold down alt on your keyboard and left click on every surface to apply that texture. DO NOT REBUILD YET. You should now have another room that looks like this:

For this tutorial only we will not add any lights to the sky box. Instead let us add in the SkyZoneInfo. In the Actor Class Browser select Info>ZoneInfo>SkyZoneInfo as shown in the pic below:

Right Click in the sky box and select Add SkyZoneInfo Here from the popup menu. You should now have the SkyZoneInfo icon located in your sky box. For the sake of this tutorial, place the SkyZoneInfo in the middle of the skybox by using the other views in the editor.

Right click on it and then select SkyZoneInfo Properties. Next select ZoneLight then AmbientBrightness. Change the value to 100.

This is a quick way to add light to the skybox without adding individual lighting. You can also select the properties on the walls and mark them as Unlit.

Move back to the original room you built and right click on the ceiling and select Surface Properties. Put a check mark next to Fake Backdrop as indicated below.

Rebuild your map and play your level. You should have something that looks like this:

Any surface with Fake Backdrop checked will act as a window into your skybox which uses the SkyZoneInfo as a camera.

Pretty easy huh? Just practice and making a sky box will be a snap. Check out the other tutorials here for making your skybox more advanced.


How to Add Decoration to Your Skybox

By: astro

astro@planetunreal.com

UED Resource Lab

What you should know how to do:

Understand the basics of a sky zone / sky box. If you do not refer to this link to find out.

Editor used: UnrealED2.0

There are many different ways to spice up your sky box. Some of the most common ways is by adding moons, planets, asteroids and so on. This can be achieved by the use of Sheets Brushes with a texture placed on it. Placing these in relation to your SkyZoneInfo (camera) can greatly enhance any bland sky box. Take a look at the pic below. I have used the sky box from CTF-Face to showcase examples of some moons and flares. I have taken the liberty of highlighting the texture so you can see how it is mounted on the sheet brush.

The default size for this texture is 256*256. Select SMoon from the ShaneChurch texture pack. Size up your sheet brush to specs and then click the Add Special button (also accessed by clicking the Brush drop-down menu and then selecting Add Special). The Add Special dialog box appears:

Select Masked Decoration from the Prefabs drop down menu.Check 2 Sided and Non-Solid then click OK. Next, right click on the texture in the 3D Viewport to get Surface Properties and put a check mark next to Unlit.

Pretty easy! You can do the same thing with Lens Flare effects. Load up the GenFX texture package and select a flare to your liking:

Click on the Add Special button and select the settings below:

Under Surface Properties, make sure Unlit is checked. I personally think a flare effect looks better when it is Unlit.

Now let us add in a boulder, and then scale it's size so that it appears to be much larger in the game giving the feeling of a hunk of space debris. Open up your Actor Class Browser and change to Decoration then the ut_Decoration subclass. Select either Boulder1 or Boulder2. Right click in the sky box and add the decoration. Next, right click on it and bring up advanced properties.

Bump up the AmbientGlow and the ScaleGlow to make it stand out a bit more. Change the DrawScale to increase the size of the boulder. How about making the boulder spin? Easy. Look below:

bFixedRotaion=True, Physics=PHYS_Rotating are key here. Next all you have to do is change the RotationRate properties. Under Advanced, bStasis and bMoveable are set to True. Everything else is False. Next make sure that bStatic is set to False under Advanced. You have just created a boulder that spins in your sky box!

I give credit where credit is due. Thank you Cédric 'Inoxx' Fiorentino for an excellent map!

Here are some tips to consider:

1) The SkyZoneInfo (Camera) is your center view in the sky box. Keep that in mind when you position your decorations.

2) Mostly every decoration you add can be sized to fit the environment you are looking for.

3) Create your own textures for a more unique sky box.

4) Make your own sky box. Be original!


How to Make a Spinning Skyzone

By: astro

astro@planetunreal.com

UED Resource Lab

What you should know how to do:

Understand the basics of a sky zone / box. If you do not follow this link to find out.

Understand the basics of decorating your sky box. Follow this link to find out.

Understand how to add color and clouds to a sky box. Click here.

Editor used: Unrealed2.0

Okay, this is an easy one. There are a few things you need to do to make a sky zone rotate. Take a look at the pic below:

Notice that the only values set to True are: bAlwaysRelevant, bHidden, bMovable, and bNoDelete. Everything else is set to False. It is very important the the option bStatic is set to False. If it were set to true then the sky would stay stationary.

Now that the Advanced properties are set up the only other thing we have to change are the Movement properties.

Make sure bFixedRotation is set to True . Next, click the drop down arrow next to Physics and change it to PHYS_Rotating. The last setting to tweak here is under RotationRate. Change the Pitch, Yaw, and Roll to your desired results. The settings above are from the map CTF-Face. You may want to use different settings in your level.

Remember that the skyzoneinfo icon acts like a camera.

All the decoration that is placed around the icon will now appear to rotate in the game. The placement of the skyzone info in relation to to decorations will alter the way the skyzone looks. Play around with the positioning until you get the look you are looking for. Below is an example:

That concludes this tutorial. The rest is up to your imagination. The only way to truly learn the depths of sky zones is to try different things. Experiment!

Thanks again to Cédric 'Inoxx' Fiorentino.


Rotating Skyboxes

By: NVerxion

nverxion@hotmail.com

This should be fairly easy to follow since I have the editor here and I can write the steps to what I'm doing as I go along. Instead of referring you to another skybox tutorial for the basics, I'm going to build a very small example level from scratch for those of you who are new to this topic so you can see how to get started. I'll try to be as clear as I can in explaining what I'm doing here. I will be describing the process…leaving the artistic aspect up to you. Just follow along and you'll end up with a reference you can expand on.

IN THE BEGINNING...skybox basics

I'm assuming you know the simple things, like adding and subtracting to and from the world, altering brush dimensions, adding lights, adding a PlayerStart, etc. As I said before, this will end up being a tiny example map showing off a rotating skybox. But first thing's first. Start a new map and carve out a room about 256x512x512. Place a light on the ceiling and add a PlayerStart.

Next make your cube 200x400x576, making sure it is still centered within the room in each view. Hit Ctrl-N to intersect, then hit Ctrl-S to subtract. By doing this, you have created the east and west window frames with one brush instead of two. Think of it as being economical.

Now, in the overhead view, hold the right mouse button and press and hold Ctrl. Move the mouse to the right to rotate the brush 90 degrees. It should still retain the shape of the two window frames, so when you have it in position all you have to do is hit Ctrl-S again to subtract and we have all four window frames in place, using only two brushes. This just makes less work for the CPU when playing the game.

Now select all four "window" surfaces (their dimensions will be 200x400) by holding Ctrl and selecting each of them in turn. Release Ctrl and right-click one of the highlighted surfaces and select Surface Properties from the menu that appears (it should say there are 4 selected). Under the Effects tab in the Surface Properties window, check the box that says Fake Backdrop, then close the window and de-select the walls.. What this does is it tells the game to show whatever is in the SkyZone (skybox) rather than the actual texture of the wall as seen in the editor. From this point, as far as the room is concerned, you can dress it up with different wall, ceiling, and floor textures if you want. Now the only thing left to do is create the SkyZone itself.

Make your cube about 512x512x512. An average size for a skybox would be about 1024x1024x1024 for an average size level. However, since our level here is so small, 512x512x512 will do fine. Keep in mind that a skybox can be any shape, but for simplicity's sake I'll use the cube here. Move the cube off to the right somewhere so that it doesn't touch the room we just made. Go over to the texture bar and load the ShaneSky.utx texture package. At the very bottom of this package you will find a texture called STARS. Select this texture and subtract the cube from the world. This will be our skybox. Technically, you could use whatever texture you want, but for a rotating skybox you will probably want to be in space, although you could get creative…. Anyway, move your viewpoint inside the cube so you can look around and select all six surfaces while holding Ctrl. Release Ctrl and right-click one of the surfaces and bring up the Surface Properties window again (it should say 6 selected). Under the Effects tab in this window, check the box that says Unlit. Now close the window and de-select the surfaces.

Almost done! Just a few more things to do
Move the cursor to the upper-right corner of the screen to the Browser. It should say textures now, if you've been following along. Click on the Browser and select classes from the drop-down menu. Scroll down the list that appears and click the minus sign next to the word *Info. From the new list that appears, click the minus sign next to the word *ZoneInfo. In this sub-menu, select SkyZoneInfo. Next, right-click one of the skybox surfaces and select Add SkyZoneInfo here. An icon should appear that looks like a picture of a cube with a question mark next to it. Now, using the overhead and side views, position the icon in the center of the skybox. That's it!! Now the only thing that remains is to REBUILD THE LEVEL and then save it

If you want to stop there, that's fine. I will now explain exactly how to make our skybox appear to rotate. If you are having any problems so far, please email me! I'll send you a copy of the map I made along with this tutorial so you can see exactly what I did. Keep in mind that my map will have a fully rotating skybox instead of a static one, but the only difference is in the SkyZoneInfo properties, not the actual construction. For those of you who want a rotating skybox, read on!!!

THE ROTATING SKYBOX....SkyZoneInfo Properties

Continuing from where we left off, there will be no further construction necessary. All that remains is a little adjustment in the SkyZoneInfo Properties.
Right-click on the SkyZoneInfo icon and select SkyZoneInfo Properties from the menu that appears. Click the plus next to the word Advanced. Scroll down the list that appears until you find bStatic, and change it to False. Next, close the advanced list, and click the plus next to the word Movement. In the new list that appears, change bFixedRotationDir to True, and change Physics to PHYS_Rotating. Next, Click the plus next to RotationRate, and change the Pitch, Yaw, and Roll settings to your liking. In this example map here I will use 150 for the Pitch, 40 for the Yaw, and 550 for the Roll.

Pitch- forward and backward rotation
Yaw- left and right rotation
Roll- banking rotation (left and right)
NOTE: Try using negative values to rotate in the opposite direction.

Well, that about does it. PLEASE email me if you have any questions concerning skyboxes. If you want a copy of the map I made for this tutorial I can send it to you. It isn't very big Just give me an address to send it to.

-Nverxion
nverxion@hotmail.com


Adding Color and Clouds to a Skybox

By: astro

astro@planetunreal.com

UED Resource Lab

What you should know how to do:

Understand the basics of a sky zone / box. If you do not follow this link to find out.

Editor used: Unrealed2.0

Let's continue with the level in the previous tutorial. Browse to the sky box in the 3D viewport. Remember the dimensions were 512*1024*1024. Select Sheet Brush properties and size a Sheet Brush to 1024*1024. Set the Axis to AX_Yaxis. See the pic below:

Now the sheet brush is lined up horizontally and you can guide it into place using your top and side views. Being this is a small sky box, I will line it up like this:

I am going to keep the SkyZoneInfo (camera) in the middle of the sky box for now. I can always adjust that later if I need to. Now comes time to pick a texture. If you have a custom one that is great. If not try the GenFluid texture pack. It has a good selection. I chose Skytst9. It is a good texture to apply colored lighting to later on.

Next, click the Add Special button. Select Masked Decoration from the Prefabs drop down menu. Put a check next to Transparent and 2-Sided.

Click OK.

I am going to change the AmbientBrightness under Advanced Properties of the SkyZoneInfo [image] back to 0 (zero).

Highlight every wall in the sky box and change the Surface Properties so that Unlit is checked.

If you rebuild now you will notice that you cannot see the clouds we put in the sky box. That is because we currently have no lighting! Well let us put some lights in the skybox. Right click on the cloud texture we just added in the sky box and select Add Light Here. You should now be able to see the clouds:

I think that would look much better if it were a different color. I am going to change it so that it looks purple. Double click the light to bring up Light Properties. Click the Plus + sign next to LightColor then click the Color button.

I boosted the LightBrightness up to 130 and the LightSaturation down to 50. I increased the LightRadius to 100 to help get rid of a light source hotspot on the cloud texture.

You should now see something like this:

The lighting will not impact the star texture in the sky box because they are set to Unlit. Copy the light a few times and spread them across the surface of the sky texture.

Now rebuild your map. Looks pretty good huh? You may have to pull the lights away from the cloud texture to adjust the look.

What's that you say? You want to have the clouds pan across the sky? Simple. Right click the cloud texture and bring up Surface Properties. Put a check next to U-Pan and V-Pan. The pan speed can be modified under the SkyZoneInfo Properties dialog box. To slow it down, change the values to .2 next to TexUPanSpeed and TexVPanSpeed.

Now it is time to do another rebuild and check it out in the game:

Looks good! Add some more decoration into the mix and you can come up with an excellent original skybox. Good luck!


Vertex Editing

    By: Mark Poesch

    1) Within UnrealEd, select a wireframe render mode, or use a window already in wireframe for vertex editing.

    2) Select the brush to modify by left clicking on an edge (this will allow you to see the current pivot point).

    3) Select the desired vertex with a left click (right clicking will select the vertex, and snap that vertex to the grid -- moving the entire brush relative to the vertex).

    4) With the target vertex selected, hold the Alt key, the left-click-and-drag the vertex.

    NOTES:
    - Grid snapping behavior is still not consistent -- turning off the grid-snap, selecting the vertex, then turning on the grid-snap, then moving the vertex usually works when nothing else does.

    - Vertex editing will snap to adjacent vertices -- this is intended. Unfortunately, there is no good way (currently) to separate the vertices once they're aligned. (Vertex editing affects all vertices within the SnapDistance radius simultaneously.)

    - A "too few vertices" error can cause the editor to crash if too many vertices are edited into the same plane.... I wasn't able to track down the bug before Unreal shipped. Sorry.

    - The current implementation of vertex editing is not production quality (hey! I got it working in less than four hours. :) Make sure you save your work before you use the feature.

    Mark Poesch
    Legend Entertainment


Vertex Editing to Create a Ramp

Jason Pharis-Pina

jimmerjammer411@planetunreal.com

http://www.planetunreal.com/ivebeenfragged

Here Im gonna show you how to make a simple ramp by vertex editing. It doesent take long and can easily be done in well under 30 seconds.

The first step is make a room. I made a room 512*512*512 and applied texture. see below.

Now create a 32*128*128 brush. position it against a wall 128 units above the floor. Heres how I did it.

Top View <--Top View

Front view <--Front View

Note: To vertex edit you need to hold down the ALT key while LEFT click dragging a selected vertex in one of the 2d views.

Ok now in the FRONT VIEW drag the vertexes on the right side of the brush down the the floor. Like the following. Do it only to the bottom vertexs on the right side of the brush.

Starting to take shape? well were almost done. Now select the top vertex on the right side of the brush. and drag it 32 units to the right (or two steps if your grid is set to 16) and then drag it down to the floor. it will come out looking like this.

Now do that to teh other vertex on the top. like the following.

Now rebuild (F8). it should look like this.

Bah! what an ugly texture job! but thats what the ramp looks like. You can use vertex editing to make lots of different things, just keep in mind that the shape you make must have as many vertexs as the original shape other wise you get a "Not Enough Verticles..." error and the editr crashes. Also dont collapse verticals down on each other, you will get the same error.


Complex Brushes

Complex Brush Shapes

    Provided by: unrealed.exe

    Tomasz ‘Millennium’ Jachimczak

    tomasz@planetunreal.com

    This tutorial will deal more with the actual creation of brushes then with the implementation. Using a brush is easy, but actually creating one is a little more difficult. This tutorial will show you how to create a simple table into one brush. I will not be telling exact sizes or anything like that, but you will be able to follow quite easily.

    The Table Top : This will be the easy part. All you have to do is to create a simple cube with the size of the table that you want. Make it either square or rectangular if you like, but make sure that it is not to think, otherwise the table will look awkward.

    The Legs : The legs of the table are another simply thing to do (Do you see why I chose a table for an example now? Hehee) Make a brush that is the shape of a long piece of wood. use something that will sit under your table and then allow the table to "rest" on it when it is complete. When you choose how thick, and how high you want your table legs to be, an them in. I will be using pictures here from a table that has got six legs and is pretty close to the ground, but that is merely an example.

    The Edges : You could leave your table at that, but why not add in some edges for the underside of the table to add in that little "extra" and make the table look once more that little more realistic. Make a brush in the shape of a basic plank of wood, then place it so that each end will reach a set of legs, but no poke through into the other side of the leg. If you find that you brush is too long, don't "scale" the brush, but change the actual length of the cube that you are using. If you scaled the brush, it would later effect the textures on the brush, and that would look poor when you actually used it in a level later on. When you have got the plank in between two legs, just under the table top, intersect the brush, and then add it into the world. Repeat this process until you have got the entire underside of the table with an edge.

    When you have done the steps that are written above, you will be able to create one brush from the entire table. To do this, create a brush from one of the primitive (anything, but most likely a cube brush) and make it large enough to "surround" the table entirely. (For example if you table is roughly 200 wide, 150 long, 64 high, then make a brush that is 220 x 170 x 80) and place it so that the table does not protrude from any point within the cube. Now simply press the intersect button and it will change your red builder brush into the shape of the table. You could use this brush straight away, but I would suggest placing it off to the side, and making a table there that will not be used at all, so that when you go to use the brush again, you will be able to do a simply "copy polygons to brush" and then use it wherever you like.

    If you do create a nice complex brush (even if it is quite simple) please send it down to the site so that we can post it here and let everyone use them. If you would like to save your brush at this point, make sure that the red builder brush is the shape of you table (or whatever you built) choose the brush menu and select "export brush". This will then give you the option of exporting and saving the brush.


Iris Doorways

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

Forward:

This Tutorial was Requested by Lance (lance@houston.crosswinds.net). The question was how to create Iris Doors. Well, here is the tutorial... :)

Abstract:

Iris Doorways are actually quite easy to create, but take some time and effort to make nicely (Attension to detail and exact measures are VITAL!). This tutorial will however explain the trick to it... It is a long tutorial with heaps of screenshots as it has to be done PERFECTLY otherwise it will look HOPELESS!

Assumptions:

I have placed this tutorial in the "Advanced" section because I assume that you know how to create a mover (and Make it work) and I am also assuming that you have a pretty good understanding of UnrealED.

Tutorial:

Introduction:

I will create a simple room, then build a wall to "cut" it in half. This will then allow a doorway to be made. The doorway will be edited, then finally the "Iris Door" will be placed into the doorway and made to move... :)

The room:

I will only say that the room I have created this door in is 256x512x512. The textures are up to you, although with doors like this one, a futuristic theme certainly adds atmosphere. The wall placed to "cut" the room in half is 32 thick (Note this as, it !!HAS!! to be otherwise the doorway will look horrible).

Creating the Doorway:

The hole for the door is simply a "Cylinder" on it"s side, (Height 32, Radius 128 - This will make it "touch" the floor and ceiling.) Make sure that the hole sits either on the floor and ceiling, or has a "ledge" within the wall for it to "touch". (This is a little hard to explain, but I think most of you get the drift.)

The doorway:

I think a little explaining is needed here, so I will give away trade secrets and tell you guys how these doors work. It is simply made up of multiple movers that respond to one trigger on each side of the door. Now for the next step, you will need to create the same cylinder (only this time make it 16 tall - which should make it narrower then the doorway you created earlier) either off to the side (or best of all - just outside your level). When you have created the Cylinder (textures are not important at this point) move on to the next phase...

"Cutting" a segment:

Now that we have our doorway cut out, we need to create some movers to fill it back up again... Create a "Cube" brush (Make it about 256x256 but make it 8 wide) and place it over the "fake" doorway you created off to the side. Now align it so that you get a quarter of the doorway and "intersect" it.
Now place this new brush NEAR the doorway, but make sure it floats freely (ie - make sure that it doesn"t touch the floor, walls or ceiling) and "add" it to the level. You should see a little segment of your doorway there now. Make sure that the correct texture (scaling, alignment ect) is applied to the segment, and finally "intersect" the segment (Once again with a brush that is larger than the whole segment to ensure it is done correctly (This is why you had to make sure the segment doesn"t touch the walls, floor or ceiling ect earlier). When you have your new brush, move on.

Creating a mover:

Now that you have a nice little segment of the doorway, place it inside the doorway (Inside the actual level) and align it to sit just touching the walls. Make sure the innermost point is in the middle of your doorway.

This image is the "Side On" view of the segment being placed.
When you have placed it just right, click the mover button. Don"t change any setting yet, but rotate the ORIGINAL brush 90 degrees, and move it so that one side touches the mover you just created and the other sides line up with the walls around it.

When you have done this, create another mover and repeat this process until you have all four quarters of the door made into movers.

Cutting another segment:

When all four Segments are in place, go back to the "Cylinder" that you created off to the side, and "Cut" another "Segment" from it, but this time make it at a 45 degree angle to the first segment that you made. (If you are not sure what the heck I mean, Have a close look at the Images supplied) When you have cut another quarter of the doorway,

repeat the process above and create the second layer of movers in the doorway. These should be placed to just touch the original set, but not sit inside them (Once again, look closely at the images). When you have placed all four - once again, 90 degrees rotated each time - move on to the next section.

Setting the movers:

When you have the eight mover placed nicely in the doorway, select ALL of them at the same time, and bring up the advanced properties (Right Click - but you should already know that) and select the "Events" section. Name them to something like "IrisDoor".

Then select the "Object" section and change the "Initial State" from "Bump Open Timed" to "Trigger Open Timed".

You should also change the time that your door takes to open (After all this work, you want people to admire it - don"t you?). This is done in the "Mover" Section and the entry to change is (Suprisingly... :) "MoveTime" Change it to about 5. You can add sounds to these if you like (Check out the Intermediate Tutorials - under Doors and Movers - if you aren"t sure how), but we still need to add in a trigger. Select "Trigger" from the classes menu (Nothing special - just a plain old trigger) and place one in front of your door (The 3D view is probably the easiest). Select the trigger (Only the trigger) and go to the "Events" section and change the "Event" entry to "IrisDoor". Don"t Forget to place one on each side of the doorway...

Setting the Trigger:

Select "Trigger" from the classes menu (Nothing special - just a plain old trigger) and place one in front of your door (The 3D view is probably the easiest). Select the trigger (Only the trigger) and go to the "Events" section and change the "Event" entry to "IrisDoor". Don"t Forget to place one on each side of the doorway...

Last but not least:

Now that you have done all the hard work, it is simply a matter of creating a cube (512x512 and 16 Wide) and placing it directly in the middle of you doorway and "Subracting" it to allow your segments a place to move to... Rebuild, and enjoy...


By

 Turning/Rotating Brushes

By: Eradicator
monre@yebo.co.za

Forward:

This is my first tutorial, and I assume that if you are reading this tutorial you must be as inexperienced as I am. But just think about it, even Inoxx used to be inexperienced – whether in his past life or what doesn’t matter much!

Abstract:

Have you ever wondered how to build diagonal walls, or inclined walkways? Well here’s a simple way- maybe not the only or the best way to do it, but hey, if it’s fast, simple and easy to do, why not?

Assumptions:

You know how to make a room, put a playerstart in it, how to move and shape your brush, and deal with textures.

Tutorial:

Introduction:

I haven’t read in any of the other tutorials how to do this before I stumbled upon doing it by accident. You kow how you move anything around in the map with Ctrl or Shift and dragging? Well, have you tried dragging it across the room with your right mouse button? That’s it! Now, depending on the 2d view, you’ll be tilting or turning your brush. So, since then I haven’t bothered again with changing the entries in the builder brush’s properties if my walls or whatever faced the wrong direction. Why not just swing it 90 degrees?

The only problem, though, is that your builder brush stays in that position, including others like stairs etc. And sometimes you could get a little carried away by all the swinging and tilting that you’ll have a hard time turning your building brush back to its default position! The only advice I can give is this:

Overhead View:

Imagine you stand in front of a wall that is being rotated. It would turn diagonally across the room and probably slam into your shoulder.

Side View:

Imagine now you are standing on a narrow walk way, if it is being rotated, you would be thrown off and land on your face.

Front View:

Standing on a narrow walk way that is being rotated would throw you off to the side so that you would be landing on your side.

Just figure it out, it’s fun.


Wolf's Tutorial One - Custom Brushes

Wolf's Tutorials: Custom Brushes 1

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Introduction:

This tutorial will discuss various ways to make (and save for later use) custom shaped brushes. This is an intermediate tutorial and I assume you have used UnrealEd before, and can do basic things with it (such as make rooms, add lights, change textures, etc...). I will be using keyboard shortcuts so it is a good idea to print the Toolbar Reference in Creative Carnage's Basic Tutorial and the Keyboard Shortcut Familiarize yourself with the keyboard short cuts (invaluable) and the Toolbar (so when I say things like "click the Scale Brush icon" you know where it is). I highly suggest that you read a BASIC tutorial or two if you are just starting out, and then come back to this tutorial when you have a basic idea how to make rooms and such. This tutorial will walk you thru the process, step by step. It is suggested you follow along using the examples presented. The same principles will apply to any shapes you want to make. Once you get the hang of it then go experiment with your own shapes.

I will try to be thorough and use a lot of pictures in my tutorials. If at anytime you are not clear on something e-mail me and I will try to clarify it for you.

Other Game (Quake 2) level editors read this: There are many differences between Q2 style editing and Unreal Editing. The biggest is that in Q2 you used 6 brushes to make up a cube. EVERYTHING was added to the world, and you used CSG subtracting to carve "holes" in previously added brushes. In UnrealEd it is different. There are two types of brushes you add. Think of them ass Positive (added) and Negative (subtracted) brushes. The Subtracted ones appear brown in the the 2d views, and the added ones blue. You can only add brushes inside of subtracted areas. You use subtraction to make your basic room (remember the world starts out solid and you use the red brush like a cookie-cutter to carve out rooms) then add brushes into it for details. Any Q2 converts who used QED should be familiar with negative brushes. If you are used to Worldcraft or Qoole then you are used to using a brush to "carve" or "clip" out parts of a brush, and then deleting your carving brush. With UnrealEd you don't delete the carving brush. You shape the red brush around the area you want to carve out and then SUBTRACT it from the existing brush. If you are not clear on that e-mail me and I can give you a better example. Let's move on.

Part One - Intersecting

You should know by now that UnrealEd has built-in "primitive" brushes. Cubes, Cylinders, cones, spheres, even stairs. This tutorial will cover how to make other shapes, like wedges, ramps, etc. All these shapes will be built using only UnrealEd. If you have a 3D modeling program like 3DStudioMax and you intend to use that for making your shapes you will have to wait for a later tutorial. This tutorial will show you how to use the above mentioned primitives to make various shapes. But before I get into shape specifics let me teach you about some tools you should know about to help you better understand what we are going to do, and familiarize you with the terms we will be using.

Brushes

You should know by now that a brush is a shape (block or whatever) in 3-d level making. In UnrealEd there are different types of brushes. The red brush is your builder brush. It is the brush you will shape to make your brushes. Remember the UnrealEd map starts out as a huge block you carve your world out of. You will also use the red brush to add things back into the areas you carve out. Whether adding or subtracting brushes, the red brush works the same way. You shape it, position it, and then click the appropriate button (whether you are adding or subtracting) to make your brush. At this point you should open UnrealEd, load a texture set (I am going to use NaliCast.utx but you can use any you like), and build a 512 X 512 X 512 room. Add a light in the middle so when we rebuild it doesn't go dark. Let's build our first custom shape.

The Wedge There are several ways to make a simple wedge. For the purpose of this tutorial I will show you two ways. The second way is much simpler, but go thru both methods so you can learn how to use Intersect and Deintersect (two things you HAVE to know to make custom brushes in UnrealEd).
The Wedge Torch Holder
Okay, your room is built. Now you want to put a wedge along one wall to act as a torch holder. The overall dimensions of the wedge will be 128(h) x 64 x 64. So lets resize our red brush by right-clicking the cube icon and adding those numbers in. Click "build" and you should now have a proper sized red brush. Move this red brush to the center of the room (so it's not touching anything else) and click the ADD BRUSH button. You should now have a 128 x 64 x 64 rectangle in the center of your room, hanging in the air. Now, without moving the red brush, click on the SKEW BRUSH button. Now we skew the brush until it looks like the figure below.
Now that we have the area we want to move surrounded by the red brush, we need to do one more thing before we subtract it. Click the INTERSECT tool. What this does, is reshapes the red brush. It will "cut away" any part of the red brush that is NOT touching a solid. Press it and see what happens.

now, the red brush is only where we want to subtract, so go ahead and click the SUBTRACT BRUSH button. Now where the red brush is the rectangle we started with is brown. You can see that in the 3d view only the blue brushes show up. That is because the brown brush is a "negative" or subtracted brush, and is basically "not there" to the naked eye. "But Wolf, I don't want the wedge to look like a two-toned rectangle in the 2d views! How can I fix this? Easy. The game engine prefers you don't have a bunch of negative brushes hanging around anyway, so let's fix that. First you have to reset your red brush so it's not skewed anymore. Right click the red brush and select "reset" then "reset scaling." Now go to cube properties and resize the red brush to 140 x 80 x 80 and click "build." What this does is makes the red brush bigger than the original rectangle. Now position the red brush so that it totally surrounds the original rectangle, and doesn't touch anything else.

Now click the INTERSECT button and your red brush should re-shape itself to to the wedge. The intersect tool will "ignore" subtractions and only shape itself around additive brushes. This will make one wedge shaped brush instead of a half-positive, half-negative brush.

Now move the new (wedge shaped) red brush to where you want the wedge to be against the wall.

Click the ADD button and you should now have a wedge against the wall. Now highlight the original blue rectangle and the brown subtract we took from it.

Make sure nothing else is highlighted and press the delete key. Answer "OK" to the pop-up window which is asking you to confirm the deletion. Now rebuild the map and you should have a wedge against the wall. You can add a torchflame actor on top of it (like I did in the first picture) or whatever you want.

Saving your Brush

Great, we made a wedge! If you are using this as a torch holder you are probably going to want to use it again, so let's learn how to save it so we can reuse it later. The Red brush should still be "wrapped around" the wedge. If it's not, simply highlight the wedge, right click it and choose COPY POLYGONS and TO BRUSH. Now it should be back. Other tutorials on the web have told you to save the brush (as a .u3d file) and then load it when you want to use it again. That would be great if the tool worked! It's a bug in UnrealEd and doesn't work properly. What you really want to do is EXPORT the brush. From the file menu at the top choose Brush, and Export Brush. The default file type is .t3d and this is fine. UnrealEd likes these much better than .u3d files! Just name it (keep it simple, call it wedge1.t3d or something) and click SAVE. Now you have exported the brush to a good .t3d file. Let's test it! Click the CUBE icon to make your wedge-shaped red brush a rectangle again. Now go to Brush, IMPORT Brush, and find your Wedge (wedge1,t3d) and double click it. A pop up window will open. Make sure that SOLID MESH and KEEP ORIGINAL POLYGONS INTACT are selected and click "OK." You should have a wedge shaped red brush again. You can move this where you want it and ADD it to your world! This method works for all shapes in UnrealEd, no matter how many additive and subtraction brushes you have. Just remember to make the red brush totally surrounding the shape you want before INTERSECTING it. Always EXPORT and IMPORT brushes, rather than save/load.

Part Two - Deintersecting

So, you liked the wedge? But isn't it a little boring? Wouldn't it be cool if it were more, "jazzy?" How about a kind of conical shaped Wedge? Let's do it!

 The Conical Wedge

This method is actually easier than the Wedge example. I used the wedge to t3each you how to use the INTERSECT tool. Now we will use the DEINTERSECT tool! Okay. Let's start a new map. Again, make it 512 x 512 x 512. Now, since we want the wedge to be conical choose the cone tool. Right click it and select properties. Let's make this wedge 128 tall and an outer radius of 64, with eight sides. Don't worry about "cap height" or "inner radius" at this point. You should now have a red builder brush in a cone shape. First we need to rotate it so that the point is pointing down. One that is done, position the red brush against the wall where you want it, but leave half the cone "outside" your room.

Once you have the cone positioned right click the DEINTERSECT tool. The half of your cone outside of your room should disappear. Deintersect will cut away any part of the red brush that is not visible, whether it is inside another brush, or outside of your room.

Now click the ADD button and you should have a wedge shaped cone against the wall. Again, you can put a torchflame on it or whatever you want.

Wrap Up

Deintersect is a powerful tool. Along with Intersect you can use it to make some really cool, complex shapes. Remember: INTERSECT will remove any part of the brush that is not touching another brush, and DEINTERSECT will remove any non-visible part of the brush. The next tutorial will get into some more complex shapes.

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


Wolf's Tutorial Two - Custom Brushes

Wolf's Tutorials: Custom Brushes 2

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Introduction:

This tutorial is for advanced intermediate tutorials. It is a follow up to my First tutorial, and you should have read that first.

Part One - Beyond the Wedge

Okay, you read my first tutorial and now you are wanting to make some more complex shapes. The wedges were nice but what about other cool items, like torch holders, computers, and things like that? This tutorial will show you how to do those, too, using the same techniques we used in the first tutorial. Also we will get into a couple advanced features of UnrealEd you may not know about.

Complex Shapes

For the purposes of this tutorial we will consider a complex shape an item that is made up of more than one shape. This tutorial will show you how to make these shapes and "convert" them to a single brush you can save and reuse. Since a good light source is essential to any level, let's make a torch holder first.

Simple Torch Holder

Let's start with out basic 512 x 512 x 512 room. We are going to build our torch holder in the middle or the room. That is so when we intersect the brushes later we won't have it touching anything. Let's start with a simple shape. Right-click the cone icon and set it's properties to a height of 32 and outer radius of 64. Don't worry about any other settings. Click the build button and close the properties dialog window. You should now have a squatty little cone in the center of your room. We'll need to rotate that 180 so the point is pointing down. Go ahead and pick a texture and then ADD the cone-shape to the world. You just made the base of the torch holder (where the flame will sit). Let's make the arm that holds the base to the wall. Right-click the cube icon and bring up it's properties window. Make the cube 16(h) x 16 x 128. Now line the rectangular red brush you just made up with the base like below.

Add the rectangular brush to the world. Now, that would work fine for a torch holer, but let's be a bit more creative and detailed with it. let's add another cone. Make this one 32 high and an outer radius of 16. Now, the cone should appear pointing down, unless you reset the brush earlier. We want the cone pointing down so this is fine. Line it up as shown.

Add it to your world. Now lets make a plate that holds the arm to the wall. Make cube 32 x 32 x 16. Line it up as shown below.

Now add it. If you have been following along you should have something like this:

Now make the red brush big enough to totally surround the brushes that make up the torch holder. Check all views and make sure the torch holder is completely inside the red brush. Now hit the intersect button and you should have something like this:

Now you can save the brush if you like. Remember: The save/load option doesn't work right, so EXPORT the brush (as a .t3d) and then IMPORT it when you want to use it again. Call it something creative like torchholder" or something. Here's a tip for you. Since we have to delete the old brushes anyway, while you've got the red brush around the parts of the torch holder, and BEFORE you intersect, hit the "Select actors inside brush" button. This should highlight all the brushes that make up our torch holder. Now Intersect. Make sure the newly shaped red brush looks correct, and then hit DEL to delete. Answer yes to confirm. Now move the red brush to a position against the wall and add it. Rebuild the geometry. If your 3d view goes all dark, then open then under Mode on the window menu bar select TEXTURES instead of "Dynamic Lighting." There, it should be back now. Okay, let's put the flame on it. In the Browser, select classes, and then expand Light. Find the TorchFlame and click it. Now in the 3D view right click the top of the torch holder (the base, the first part we built). Make sure to not right click on the red brush. If the first option when you right click is "Brush Properties" then try again. If the first option is "Surface Properties" Then you are okay. Look down the menu at the second option. It should say "Add Torchflame here." That's exactly what we want to do, so select that. Now a torchflame should appear on your torch holder. Align it in the 2D views so that it is in the center of the holder base. Now rebuild geometry. If you switched the 3D view to "Textures" before, switch it back to "Dynamic lighting." It's still kind of dark in there so let's add another torch holder on the opposite wall. IMPORT the torch holder you saved earlier. We could have just moved the existing red brush where we wanted it, but we wanted to make sure we could import the brush back in. Once you import the brush, move it to the opposite wall and rotate it so it's a mirror image of the other torch holder. Now in the top-view 2D view highlight the torch flame. Press CTRL-W to duplicate it and then center the new torch flame over the new torch holder. Rebuild geometry again. Now add a player start, rebuild and then go test the room. I'll wait here for you. :)
The torch holders didn't show up very well, did they? Kind of high up and hard to see. Let's fix that. Start by going to the menu bar at the top and under Brush go to Reset. You shouldn't even have to click, it should automatically reset the brush and center it. Now, the red brush should still be "torch-holder-shaped" only upside down. That's okay, the next step will fix that. Right click on the brown brush that is our starting room. On the pop-up menu go to Copy Polygons...and To Brush. Yes, Copy Polygons to brush will make the red brush a "clone" of the one that is highlighted, in this case our start room. Now, in the top 2D view, move the red brush so that one side touches the existing start room and then press the Subtract Brush button (Remember before removing the red brush you need to either hit the Deselect All button or click somewhere in the 2D view so that the original room brush is no longer selected).

Now add a light (right click and choose "add light here") to the 3D view. In the 2D views position the light so that it is between the two torch holders, and just below them. Rebuild again and you should have something like this:

In the top 2D view move the PlayerStart icon to the far end of the new section of the room (farthest you can get it from the torches. Now rebuild and play the level again. You should now have a fairly wide, long hall with two big torch holders (with flames) at one end of the room. Walk around, looking up at the torches. The should look pretty good. But the room itself is boring. Let's try and spiff it up a bit, shall we?

Building Boxes

Whenever you are going to make complex shapes in an existing level you will want to build them in a separate part of the level and then move them where you want them. I call this little room a Building Box. I make them big so I don't have to worry about large objects touching the walls and such when I intersect them. Let's resize our brush to 1000 x 1000 x 1000 and move it out away from our existing hall.

Subtract it from the world and should have a big empty room now. I usually give this room a bright texture on all sides to make things easier to see in it. You can build all your items in this room, intersect them and move the brush where ever you want it in your level before adding it. Since I never add lights to this room, I always switch the 3D view to "Textures" when working in this room. Now, to add some details to our little hall. Let's go to the building box and build something to make our little halls less boring.

A Simple Column

I think a couple of narrow columns might be cool in there. So lets reset our red brush and then resize it to 512 (h) x 64 x 64. You should now have a tall red rectangle in the center of your building box. Pick a nice column texture and then add the brush to the world. Now a tall slender column is pretty boring, even for this tutorial, so lets add some details to it. First select cone properties and size it to 32 height and outer radius of 64. Now line the red brush up with the bottom of the column as show.

Now rotate the red brush so the cone is "upside down" and then align the cone to the top just as you did at the bottom. Add the brush. Now make your red brush big enough to completely cover the new column and intersect it. Before doing so make sure all the textures you want are on the column and aligned properly. Once intersect you have a column brush. Save it if you like (EXPORT!) and then move the red brush to our starting room. Move the column brush to any corner and hit add. Move the brush again to another corner and repeat the add. Do this until there is a column in each corner, and one in along the wall (on both sides) in the center of the room where the two halves of the room meet.

Once you have added all the columns then rebuild geometry and check it out.

Go back to the building box and delete the old brushes that made up the column. Rebuild geometry and the old brushes should vanish. Now, we need some light at the end of the hall where the player start is. We could just add a light actor there, but we would need a light source to make it seem real, so let's build another light source. We should build something different this time. Let's make some sort of floor lamp. Now, we could go to decorations and choose lamp and add that, but that would be too easy. Besides it would do nothing to show you how to make custom shapes in UnrealEd. Let's build out own!

Floor Lamp

I can hear you saying, "Why don't we build a lamp that sits on a pedestal and has these neat metal cage things all around it?" Good idea you had there. Let's build it. We'll start off by moving to our building box. Let's build the hard part first, metal cage thingy. Now we don't want this too big and we are going to have to build it out of primitives. Let's make it out of little rectangles. We'll start with a cube so resize the cube brush to 64 x 64 x 64, select a texture and add it. Now we are going to build some negative brushes and carve out our cage. resize the red brush so it sticks out of the sides, but doesn't touch the top or bottom. I made it 48 x 48 x 80. Line it up as follows:

Now subtract it. That should kind of hollow out your brush. Now rotate the red brush 180 degrees and subtract again.

Our cage is almost done, but we should put more little "bars" in it. So resze the red brush to 48 x 8 x 8. Now position the new red brush like this.

What's that you say? "Wolf, I can't line it up like that! It won't go there!" Sure it will. It doesn't want to because our grid is set to 16 and when it snaps to 16 our little 8 unit wide brush won't line up right. To fix it just reset the grid. In a 2D view simply right click anywhere on the grid. Go down to "Grid" and choose 4. Now it should go where we want it. Once you get it where you want it, add it to the world. Now move the brush to the opposite side (keeping it centered like we did the first one) and add it. Continue until you have four little "bars" in your cage. Now we have the cage built, but remember this is going to be a floor lamp, so we need a base. Let's make the red brush 64 x 32 x 32 and center it on the bottom of the cage. Now add it. Now, the base of the stand: resize the red brush to 16 x 64 x 64 and position it at the bottom of the stand and add it. You should have something like this:

Now we simply have to build the red brush big enough to surround the new lamp, and intersect it. Move the newly lamp-shaped red brush where you want it and add it. I put mine in the center of the hall, touching the floor of course, between the PlayerStart and the second set of columns.

Now add a light actor right in the center of the cage part of the lamp. Now rebuild the geometry and make sure you set the 3D view back to "Dynamic Lighting." You should now have a lamp that casts some really cool shadows! "But Wolf, it doesn't look like a lamp. It just looks like a cool little cage giving off light!" Well, that's because there is nothing inside it. What we should do now is add a TorchFlame to the center. WOW! Much too big a flame for that little cage. Here's how we fix that. Click the TorchFlame to highlight it. Now right click it. A TorchFlame Properties window should pop up. Expand "Display" and go to DrawScale. It should be set to one now. We should make that about .2 (point 2). Now it should look better. Rebuild again. That is much better. You should have something like this:

Give Me More!
So this is great! Why don't we put an Arched doorway at the other end of the room, and maybe some steps and stuff... Go right ahead. It's your map. But if you want to learn the best way to do Arched Doorways and stuff, you will have to wait for the next tutorial "Using the 2D Shape Editor."

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


New Page 1

 Curved Brushes

[P&B]Holo_Duke
Holo_Duke@yahoo.com

Tutorial:

Want to make a map with nice curved surfaces/corridors?? like Dmzeto. Well here is it.

For beginners its very frustrating to make that, cause vertex manipulation should be used. Some people say that the vertex tool sucks cause its loaded with bugs, but it is not. For now I will explain to make a simple rounded room.

First of all remember to set your rotation grid to 16. ready?? ok now carve a simply 256*512*512 box (a box with orange lines) now the hardest part of this tutorial will start. only people with a lot of experience in 3d editing will understand this. create a 256*64*64 box (a box with blue lines) in the center of the carved 256*512*512 box.

Duplicate it twice so you have 3 256*64*64 boxes and place it to each other. now its time to use the rotation tool. press with the left mouse button on upper right corner of the left 256*64*64 box. you will see that the upper right vertex is activated. now make sure you have selected the rotation tool again. click with the right mouse button on the upper right vertex and hold it!! move your mouse to right so that your brush rotates 2 steps. Ok, your left brush is done, further with right brush (blue lined box) click again on the rotation tool and click on the upper LEFT corner/vertex rotate it from that point to the opposite direction of the left brush (also 2 steps) (move your mouse to the left. The first part is done.

REBUILD your level, (Else your vertex manipulation will NOT WORK!!!) You will now have a 2 turned 256*64*64 boxes and 1 normal 256*64*64 box and a large carved out brush.

Ok, now its time to use the vertex tool. (you can move a vertex when you hold alt and press the left mouse button and move it with your mouse. TIP: To select it use alt+Right button and make sure that the red dot is exactly on a corner, if not move your brush a several times and try again).

Move the lower right vertex of the brush in the middle 256*64*64 to the lower left vertex of the right brush 256*64*64. and.. the lower left vertex of the brush in the middle to the lower right vertex of the left brush 256*64*64. Now delete the left sided and right sided brushes so you only have the vertex modified brush 256*64*64 and the large 256*512*512 brush. Second part done.

Now duplicate the modified brush once. move your brush with the upper right vertex (do not use the vertex tool) to the upper left vertex of the original modified brush. Rotate it to left so it fits exactly on original modified box. Do the same with the right side. easy easy!! but don't forget its not ready yet. there are now 4 brushes visible the original, the curved copies of the original and the large one.

Look at the upper left vertex/corner of the left brush (the duplicated brush) Zoom and you will see that the vertex is not placed on a grid. now duplicate that brush and try to connect the brush like we did before. Even when you turn down the grid size its impossible to connect. but wait there is vertex snapper isn't it????? right!! try it if you can.

Huh?. It doesn't snap, why???? BECAUSE YOU FORGOT TO REBUILD AGAIN!!!! ok, after you have rebuild it, it will snap you will see. now finish the circly by duplicating and snapping those modified brushes.

I have spend weeks before I fully understood how vertex modification and snapping works. its very frustrating if you don't know how to snap vertexes. this example of one single rounded room. is very simple thing to made if you know how to made. there are very complex things possible by using this method like making curved doors, spheres, everything almost!!! but it will take time a lot of time but you will get something.


Rotating Objects

by: Knives
knives@i-2000.com

For our example, we"re just gonna make a simple rotating column in a small square room. Not very useful in the real world, but will be easy enough for you to follow to the letter.

1: Fire up Unrealed, and carve out a 512 cube room. (if you don"t know how to do this or anything else in this tutorial, you need to back to the basics. I reccomend the basic room tutorials on unrealed.net.) Put your player start and one light in your room.

2: Next, while you still have a 512 cube tool, carve out another room completely seperate from your player area.

3: Next we"ll make the brush you"re going to use as your rotator.. We"ll make an 8-sided cylindar, 16 high and 128 radius (128-16 inner). Don"t add it yet! Move this into the center of your second room, making sure it"s not touching any walls in any view. Add the brush to the world, and texture it the way you want it to look.

4: Right-Click the CUBE button -> Properties again, this time making the brush a 360 unit cube. If you started from a clean slate, following my instructions completely, the red builder cube should completely surround the cylindar, and be completely inside your second room. Make sure you look at the following screenshot.

*IMPORTANT NOTE: At this point you should not have used the scale, resize, or rotation tools. But many times you will have, so this is what you need to do before continuing:
a: click on the brush tool so it"s all red -> right-click -> Reset -> Scaling
b: click on the brush tool so it"s all red -> right-click -> Reset -> Rotation
If you have manually resized or rotated the red brush tool, YOU MUST RESET rotation and scaling of the red brush tool before continuing this tutorial! If you don"t reset the size and rotation, the mover WILL NOT WORK!

5: Click the button below the Subtract button, "Intersect." If you"ve followed my instructions correctly, the red builder tool will now be the same size and shape as the cylinder. Move the red builder tool into your player area and align it so it touches the floor, in the center of the room. Click the colunm 3, 6 from the top, "add mover" (white cube with swirlys coming out of it.)

6: Now that we"ve created our mover, there"s really only one remaining step, setting up the Mover Properties. Click in the Top View and hit B. This will hide the tool brush, revealing your mover as a blue cylinder. click on the edge of this brush, and it will become bright blue. Next, right-click -> Mover Properties. Change to the following properties:

+Brush:
CsgOper: CSG_Active

+Events:
Tag: ThisMover (can be anything, just make sure it"s unique)

+Movement:
bFixedRotationDir: True
+Desired Rotation //as far as i can tell this is just -1, 0, 1
Pitch=0 //down/up
Yaw=1 //left/right
Roll=0 //banking left/right
Mass: 0.000000
Physics: PHYS_Rotating
+Rotation: (Pitch=0, Yaw=0, Roll=0) //this is positioning. you shouldn"t need this.
+RotationRate: (Pitch=0, Yaw=5000, Roll=0) //turn speed.

+Mover:
bDamageTriggered: True (i set this to true and set damage to 10000000; u may not need)
BumpType: BT_PlayerBump
DamageThreshold: 100000000.000000 (again you may not need.)
KeyNum: 0
MoverEncroachType: ME_IgnoreWhenEncroach //Optional action when player blocks
MoveTime: 0.000000
NumKeys: 0
Other Time: 0.000000

+Object:
InitialState: None //this is the important one! this makes the brush ignore the player.

Rebuild the map and give it a try! I think that should do it!


By

 Turning a Polygon Around

By: DaveA
Dave_Arendash@intuit.com

As you may or may not know, polygons have two distinct sides. You can prove this to yourself by flying around in the 3d view in the editor, and watch as you move from one side of a polygon to another. The side you can see is the good one.

There may be times when you need to turn one around. If you are doing Zone Portals, this is likely to happen to you. Zone Portals are generally 'sheets' which are just simple polygons (not part of a polyhedron, or 3d brush, as such). These are easy to turn by hand.

Pick a view where the sheet is edge-on to you (looks like a line). Vertex edit: let's say you have a rectangle, vertices A,B,C,D, and A & B are overlapped, as are C & D.

Drag vertex A out, which gives you a triangle.

Drag the one that was under A, namely B, out of the way too.

Now, drag the other end's vertices (C and D) to the spot where the first ones were, A & B's original position.

C and D overlapping again.

Then, drag A & B to where C & D were originally.

You now have the polygon reversed. Vertex editing ruins any surface alignment, so select the surface and hit F5 to fix it.

If anyone knows an easier way to do this, let me know.

If you want to turn a polygon around which is part of a brush, export the brush or level to t3d format. Find the polygon. You can try flipping the signs on all the components of the Normal. You could also try reversing the order the vertices are defined. I'm not really sure it that would override the normals.


Unreal Editor Maximum [unrealism.com/unrealedmax] - THE ADD SPECIAL BUTTON

THE ADD SPECIAL BUTTON

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This tutorial will put the add special button through the paces. It will deal with all the uses that this [image] button can be put through.

When you hit the add special button the dialog on [image] the left opens showing the various properties that you can assign to the surfaces of the brushes that you create and the one on the right shows the pull down menu where you have some pre-configured types that you just have to choose and add in. Lets discuss the setup and use of these pre-configured ones first. This tutorial is meant for those of you who are starting out in UnrealEd2 as some parts are really basic (BUT people who are in other levels may find the Semi-Solid Brush State part useful).
TIP: The sheet builder [image] which builds a sheet should only be used along with the add special button. This means that if you want to build something using the sheet use only the add special button and not the normal add button that you use for cubes, etc.

Tutorial Subsections - This tutorial is divided into the following subsections. Just choose any one of these topics to jump there.

  1. Water

  2. Semi-Solid Brush State (IMPORTANT)

  3. Zone Portal

  4. Transparent Window

  5. Masked Decorations

  6. Invisible Collision Hull

1. Transparent Window

Lets build a quick tutorial map and see how to make windows for your level. Build a cube 256x256x768 and subtract it from the null space in a new level. Next build a cube 256x256x32 and add it into the center of the room. Next build a cube 128x128x32 and subtract it from the center of the room - this is where you will place the window. Load the GenIn.utx or Coret_FX texture package which has got some nice glass textures.
TIP: To see only the glass textures for a certain texture package choose glass in the pull down menu below the loaded texture package (see picture to the left).
Build a sheet u=128 and v=128 with x or y orientation. In this case since we know the exact measurements of the hole for the window to go into so we can just add it using the same size. If you have a hole for a window to go into and don't know the size just build a sheet slightly larger than the hole and then add in the window. Now that the sheet is built just choose a nice glass texture (I used the SpecGlass texture from Coret_Fx). Hit the add special button and in the drop down menu just choose Transparent Window, leave the other settings alone and hit the add special button. If you did everything correctly up to now you should get a nice window in your level now.

2. Masked Decorations

Interesting and fun things to give that "special" look to your level. For now load the GenFX.utx texture package and just like we did for glass choose mask from the drop down menu below the texture. Build a sheet and place it where you want it to go and hit the add special button. Just choose masked decoration from the drop down menu and hit add special. For this example you can leave the visibility at 1-sided, but for example you may want vines hanging from the center of the room to be seen from both sides, then check 2-sided. You can make some fantastic looking stuff, everything in the following picture was done in the same way:

NOTE: The arch was created with the 2d Editor, after you become more familiar with the editor you may want to head down to the advanced tutorials section and read my 2d Shapes tutorial.

3. Invisible Collision Hulls

If you have played your level you would have noticed that you will be able to walk through the window and the masked decorations. Never heard of a person being able to walk through glass so the best way to stop players would be to set up a collision hull. What this does is place an invisible barrier that the player cannot see but yet blocks the player from passing. Just build your sheet or brush and place it in front of the glass that you wan the player to be blocked from entering and choose invisible collision hull and hit add special. In the picture above I added in a collision hull only in front the arch grate, the other decorations like the straw and vines need not have a collision hull as the player can pass through them in real life, why not in unreality.

TIP: If you are an observant person you would have noticed by now that the various types of brushes that can be added in are just a variation of the regular brush. This is in the sense that you can create everything by changing the combination of settings for the regular brush to get different types like the collision hull.

TIP2: All the different types of brushes that you can add into the world with this button will be shown by different colors in the 2d views. For example a masked decoration will be a light green brush in the 2d view, a collision hull brown and so on.

4. Zone Portal

Use this to divide the level into separate zones so that they run faster. For more information you can read the Miscellaneous Zone Classes tutorial here. Note that its best to place the zone portal in narrow hallways and such. As any advanced mapper will tell you making very large zone portal brushes can cause your level to slow down instead of speeding it up - which is the main purpose of zone portals in the first place.

5. Water

The water subclass is a prefab that helps you to build a water sheet to convert an area into water. Lets take a very simple example to see how to make water. Here's a simple five steps to making water:

  1. First make the room in which you want to put the water in - say about 1024x1024x1024.

  2. Next make the brush to hold the water -say about 256x256x1024 and place it to the side of the room, align it in the side view so that it touches the bottom of the first room and subtract it so that you get something like the following :-

  3. Next lets make the water. Since we know the size of the brush into which we will put the water lets build a sheet 256x1024 - this will be the size of the water brush. Load the genfliud.utx texture package this has all the base water textures now just select one water texture that you like. Now make sure that the sheet is a little lower than the subtracted brush that should hold the water. All you need to do now is hit the add special button and choose water and hit OK to close the dialog. The final level should look like this:-

    Notice that the water is a little lower than the brush that holds its.

  4. Now this is not enough. You will notice in the add special dialog that the water brush is nothing more than a transparent, non-solid zone portal brush. You just need to place a Water Zone actor below the water brush so that it tells the editor that this is a water zone. (You'll find the water zone actor from under info|zone info.

  5. Now just place a player start and some lights rebuild and play the level. You should be able to hear the sounds when entering and exiting the water and if you stay too long underwater you should start losing health. That's all there is to making water.

TIP: If you make the brush to hold the water using the 2D editor so that it is in an irregular shape there are two ways of making the water sheet. (If you haven't read it as yet please read the 2D Editor Tutorial its very important).

For irregular shapes outside it will be easier to build the water brush using the sheet tool. But imagine if you have a tank made using the 2deditor then it would be better to build the water brush using the 2d editor.

6. The Semi-Solid Brush

The semi-solid brush state is a very important one (the other two are solid and non-solid ............. duh!). A semi-solid brush is one that does not cut up BSP and yet blocks the player. The solid brush cuts up BSP and blocks the player whereas the non-solid does not cut up the BSP or block the player either. The semi-solid brush appears as a brown colored brush in the 2d views. The easiest way of verifying whether whether a brush is a solid or a semi-solid is by "flying" through it in the 3d view. Say you have a pillar brush that touches the floor and ceiling of a room. If it were a solid pillar and you flew into the middle of it in the 3d view, you would literally be able to look into the void outside the room/level. But if it were a semi-solid pillar and you flew into the middle of it you would only be able to see the pillar touching the floor and ceiling - you would not be able to see into the void.

IMPORTANT: Adding in a semi-solid brush is as easy as as making the brush via primitives or the 2d editor, placing it in the level where you want it, hitting the add special button and then just choosing semi-solid pillar from the pull down menu and hitting Ok.
UnrealEd2 allows you to change the state of solidity of a brush on the fly. This means that if added in a brush and later need to change its solidity to a different type you can do so. Just select the brush in any of the 2d views - or hold down shift and left click on one of the surfaces of the brush whose solidity you want to change. Now right click and in the menu that appears just scroll down the list until you reach solidity and select semi-solid, like this:

This naturally works vice-versa as well.

The semi-solid helps to drastically reduce the node count of a level (the amount of nodes or vertices that a player can see at any given time). And if the node count is reduced the level will run faster. Take for example a level that I was making - it had a total of 842 brushes - 146 subtracted, 123 adds, 518 semi-solids and 54 non-solid brushes. At this point the node count for the level was 9805:

You can get the full statistics for your level by doing a complete rebuild of it - don't forget to turn on BSP under the options tab of the rebuilder. Now I selected all the semi-solid brushes in the level and converted them to solids. Now I did a complete rebuild of the level and the Node Count jumped to 12000. Not only did this considerably turn up the node count it slowed the level down drastically - besides creating a few horrible Hall Of Mirror (HOM) effects!.

This may make the semi-solid brush seem like a dream but building the entire level out of semi-solid brushes is a terrible idea as there will be many problems with your level. You need to find a balance between excessive use of semi-solids and not at all. Some times it can be a trial and error method. The semi-solids have several problems. For example since it does not cut up BSP you cannot add a semi-solid brush to your level and then subtract from within it - you can only do it to solid brushes. Sometimes use of the semi-solid brush itself can cause the HOM effect where due to a compile error you are able to see into the void or you will be unable to move within that part. So you need to be very careful with the placement of semi-solid brushes.

Semi-solids are great for creating complex decorations that have been intersected. For example I created a chimney out of 10 brushes - 5 added brushes and 5 subtracted brushes, like this:

Notice that there are 49 nodes being drawn in this picture and that the amount of polys is 22. Now I just moved these brushes outside the level into another box and intersected them and placed the brush in the same place as before but I added it in as a semi-solid brush. Look what happened to the picture:

The node count got reduced from 49 to 32 - this may seem like a very negligible amount but if you carried out this practice in your whole level you may be able to reduce your node count by at least 1000. Its better to keep the whole total node count of your level below 10000. And this is where it can matter a lot - just a few nodes may make the difference in your level speeding it up just that extra bit.

But then again intersection is not all that it is cracked up to be. In the above case it proved to be very helpful. But it will not always be like that - intersection in some cases will actually increase the node count. Take a look below:

Some people would have considered the semi-solid brush an ideal candidate for deintersection. But if I had deintersected the original builder brush I would actually have added more vertices to the level thereby increasing the node count. That is why I have left the brush as it is jutting out with an extra bit. Again this is something you will have to decide based on the situation - you'll know when to do it as you get more experienced. But generally speaking it is better not to intersect/deintersect against irregular brushes as this will definitely add more vertices to your brush.

The semi-solid is great for decorations as I mentioned before (especially for that ubiquitous and clichéd crates that every level designer uses ;). Well learn to use the semi-solid wisely as it is great answer to many problems that you may face - especially slow levels. This part of the tutorial has been too much like a sermon and I better end it before it gets too preachy ;).


Unreal Editor Maximum [unrealism.com/unrealedmax] - Brush Clipping

BRUSH CLIPPING

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This tutorial will show you how to cut or clip away parts of brushes. Its going to be a Wham, Bang, Thank you ma'am kind of tutorial.

CLIPS AHOY!

First and foremost, go into brush clipping mode by hitting the button given on the left, you can get out of this mode at any time by hitting the camera button - [image].

REMEMBER: You can perform a brush clip on the red active builder brush or on any brush that you may have added to the world before.

Now after having enabled the brush clipping mode, make a builder brush - 256x256x256 should do just fine for now. When you position the cursor now over any of the views you will see that the crosshair has changed to the clipping crosshair. Clipping works by assigning two points (or three points) that define from where to where the brush should be clipped. The following shows the various functions that are available:
Use will be explanined later on.

First things first, lets place the clip markers that tell the Editor the area which we want to clip away. Now since we are already in "BrushClip Mode" and have a brush that we want to clip, do the following to place the first clip marker:

HOLD DOWN CTRL+RIGHT MOUSE AND CLICK IN ANY 2D-VIEW
You can select the clip marker at any time by just left clicking on the clip. Now select the clip and move it to the same place as I have done:

For now we will place a total of only two clip markers. Place the second clip marker like how you did the first one and move it to the following positions like this:

The direction in which the clipping marker is facing is important as this is the part that will be clipped (cut?) away or destroyed. You can flip or turn it the other way by hitting the flip normal button [ [image]]. In the above picture if you wanted the right side of the line between the two clip markers to be clipped away you just need to flip the normal first.

After the placement of clip markers performing the clip is as easy as first selecting the brush to be clipped and then hitting this button [ [image]]. The part facing the normal just gets cut away like in the picture below:

TRANSFORMING A BRUSH PERMANENTLY

If you keep trying to clip a brush and you are unable to do so you need to first transform the brush permanently. To transform a brush just select it right click and in the menu the appears, under transform hit Transform Permanently.
NOTE 1: It is not necessary that you have to transform all the brushes, if clipping doesn't work then you can proceed with the transformation and then try again.
NOTE 2: Will usually crop up due to vertex editing.

SPLITTING A BRUSH

This button allows you to do just that. Its like taking an axe and splitting wood into two:

Use this button to clip away parts of brushes that have been added or subtracted to the game world.

3D CLIPPING

Till now you used only 2 clip markers this is referred to as 2d clipping as this involves using only one of the 2d views. When you introduce the third clip marker this is called 3d clipping, since you will have to adjust the 3rd clip marker in at least one other view. Try this, first introduce two clip markers and align them in a line in the in the side view and then introduce the 3rd clip marker and move it slightly up (see picture):

Think of 3d clipping as proceeding from point 1 to 2 and then to 3.The editor first clips away the part from the 1st clip marker to the second clip marker (like how we did manually in the first part of the tutorial), with this brush it then automatically proceeds from 2 to clip point 3 and clips the brush again. What you see is the resulting brush. You may need to reread this paragraph a coupla times to figure what I mean. The best way to verify this would be to first clip the brush manually using 2 clip markers, then with the resultant brush move clip marker 1 to the same position that clip marker 3 was in the 3d clip - now if you perform a clip (a split actually since in this example it is a subtracted brush) you will get the same brush as before.


By

Brush Clipping Tutorial (in UnrealED 2)

By: EpsCylonB
burchill@btinternet.com

What is it... ?

Brush clipping is where you assign points (clip markers) onto the face of a brush, then you can clip away a part of the brush. This is called 2D Brush Clipping, UnrealED 2 supports 3D Brush Clipping as well, this uses a third point, but is beyond the scope of this tutorial.

What this Tutorial is going to do...

We are going to do a 2D clip on the red builder brush.
You can use brush clipping on any brush (additive, or subtractive) but for the sake of simplicity we will use it on the builder brush. Tutorial...
Open up UnrealED 2. You should have a blank level. Click on the cube bottom on the left hand side toolbar. You should now see a red builder brush.

Hold down CTRL and in one of the 2D views somewhere near the side of the builder brush (not on the builder brush as this will bring up a menu) right-click. You should now see a clip marker (at first it may look like a vertice, but zoom in and it should look white). Holding down CTRL move the clip marker onto the side of the brush.

Add another clip marker in the same way on the other side of the brush. Make sure you do this in the same 2D view. You should now have something that looks like this...

Click on the builder brush (so that it is selected) and then press the brush-clip button on the left hand toolbar...

This should be the result...

Notice that the part that was destroyed was the part that the normal was facing.

The Other Brush-Clip Buttons...

We know what this one does, it clips away the part of the brush which the normal faces.

This button only works on additives (blue brushes) and subtractives (yellow brushes). As well as clipping the selected brush, the builder brush will turn into the part that you clip away.

This button flips the normal. So in the above tutorial, had we flipped the normal before we clipped, the other half of the brush would of stayed and the half that did stay would have gone.

This deletes all the clip markers so you can start adding them again. Note that if you try to add four clip markers then the same thing will happen (all clip markers will be deleted).

3-D Brush Clipping...
To do three dimensional brush clipping you add a third clipping marker in the same way as said in the tutorial. The difference is that with 2D brush clipping, you work in one of the 2D map views, with 3D brush clipping you have to add add the first two clip markers in the same 2D view and then the third in a different 2D view. The results of 3D brush clipping are not easily explainable so it is best just to try it to see what results can be obtained.


Vertex Editing

by FragMasterZen

FragMasterZen

For both of these make sure the brush is selected before you try to select the vertex.

Ok this is going to be a quick tute on how to move individual vertices around. You may not use this very much, but it can sure help to know at times. Anyway, vertex editing couldn't be easier. Just click on the vertex you want to move, and make sure it has a little crosshair over it, which indicates it is selected. Then(if you are in camera view) press and hold the alt button and the left mouse button and drag the mouse. You can also move it by holding both of the mouse buttons.

If you want to move more than one vertex at a time you have to go into vertex editing mode. This button is just to the right of the camera view button. Once you are in this mode you can select multiple vertices to move by holding ctrl+alt+LeftMouse button and drag the red box which appears over the vertices you want to move. Now release the buttons and move the selected vertices(which are now white) and use the same procedure for moving one vertice except hold the ctrl button instead of the alt button.

Vertex editing is used most often to make terrain with the terrain builder brush.
-FragMasterZen


Vertex Editing

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

How to go into vertex editing mode?

To enter vertex editing mode, click the vertex editing button is the modes section of the left hand toolbox.

You can also bind a key to switch vertex editing on and off. Bind a key to the following command:
MODE SHOWVERTICES -1

Are there any other things I should know before I start?
  1. Set the vertex color to something bright (like white)
    Goto View->Advanced Options->Editor->Color->C_BrushVertex and change it to white
    This will mean that the vertexes should now show up properly
    N.B. Post version 430 this should be set up automatically.
  2. You can screw up your complete map if you get this wrong, so always do a save!
  3. Don't forget you can create 'invalid' surfaces if your not careful, e.g. a square surface with one vertex below all the others is not valid
  4. I've had lots of trouble with single vertex editing and always use the drag-select detailed below
  5. I've come across various glitches on my PC check out my "Vertex Bugs" at the bottom!
How do i select one or more vertex

The first thing you must do is select the brush you want to edit. Simple clicking on the brush should accomplish this task.

Clicking on the vertex should select each vertex. (It doesn't work on my PC, but hey, thats life)

Holding down control and clicking should select more than one vertex.
How do I use the new Drag-Select function with Vertexes?

The function is used by holding down the Ctrl+Alt keys, then left clicking and dragging a box around one or more vertexes. It is best if you release the mouse button before releasing the keys, as sometimes it might leave the box on screen if you do it the other way around.

If you want to select vertexes from more than one brush then hold down the Ctrl key and select the brushes in the normal way, you will see their vertexes appear as you do. Then you can select their vertexes in the the above manner or using the Drag-Select manner described here.

The vertexes which are selected are defined by those which are contained within the drag-box.
How do I move Vertexes?

You move vertexes exactly like you move brushes, holding down the Ctrl key and Left-Mouse button and moving the mouse. I find it is best to press the Ctrl key first, then the mouse button. After moving depress the mouse button before releasing the Ctrl key.

If you select some vertexes and then click in another view it may deselect your vertexes. If you hold down the Ctrl key as you click on the next view this should keep them selected.
Vertex Bugs? My Experiences

Aside from the above mentioned fact that I cannot get single selection of vertexes to work I have to say that vertex editing finally seems to have settled down.

One reason for this is I believe the fact that you can no longer move and entire brush while in vertex editing mode (aside from selecting all the vertexes obviously!)


BB Drac - Unreal Tournament UED2 guide Brush Editing, Curved Hallways

Curved Hallways

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Curved hallways, although harder to work with and slightly reduce frame rate,
it will make the level look much better when done right.

To be able to follow and understand this tutorial it is important that
you understand brush handling and creation.

From the screenshot below you can see that I have placed two short hallways and
now want them to connect.
The easiest solution would simply be to create a cube brush and subtract.
Screenshot

Instead I want a curved hallway to connect these two ends.

The best way to do this is with the 2D editor.
If you haven't worked with it yet or not too familiar with it,
I suggest checking out the 2D shape editor tutorial first.

So, in the 2D editor simply draw up a "curved" shape that would be
the hallway seen from above.

I used a grid of 16 and just made some splits and moved them all around
until I had a shape that I thought would look good.

If you reduce grid setting and add more splits you are able to
create much more "curved" walls.
Screenshot

Extrude the shape using the same value as the height of the two hallways and
the new brush should appear.
Just place it where it should connect and subtract.
Screenshot

Here comes the fun part...
Align all those textures to make it fit more with the rest of the walls.

In most cases you can just select all polys for one side, floor, wall or ceiling
and just align them to either floor or wall and they turn the right way around.

If you use "repeating" texture they should come out right and look pretty ok,
but in some more "detailed" and direction based textures you might need to pan
and/or rotate them to get it right.

Also remember that the more polys you add to the curved brush the harder it is
to align them nicely.

Now you might thinking.
What if I want sloped walls in my curved hallway?
No problem.

The other way to create curved hallways, which in my view is alot better,
is to use the 'Revolved Shape'.

Instead of creating the curved hallway seen from above and then extrude it,
you may design the hallway from the side instead.

Screenshot

This screen shot is a side cut from a hallway and I want to connect them
with a curved hallway without losing the physical shape.

By placing the green handle a bit outside the shape and then revolve the shape with
32 sides for a circle and using only 8 I get a quarter circle hallway.


BB Drac - Unreal Tournament UED2 guide Brush Editing, Ladder

Ladders

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

The alternative to ramps and stairs, by graphical means, ladders.

To be able to follow and understand this tutorial it is important that
you understand brush handling and creation.

UT do not support 'true' ladders so we need to cheat to create one.

It is done by first creating the actual ladder.
I simply put two vertical bars and some horizontal bars and intersected it
to get a ladder brush.
This I tilted slightly to the wall.
Screenshot

If you were to play this map now, you are actually able to use the ladder
as each step support a player standing.
(If the ladder is wide enough).
If you ask me this would be a bit more realistic as the player need to
jump each step and climbing a ladder isn't done in a second.
Could be really hard to bot path though.

To keep on, you now produce a stair brush that has almost the same width as
the ladder and a step height around 28 or lower.
What you need to adjust is probably amount of steps and the step length.
These two affects the stairs compared to the tilting and height of the ladder.

When you got a shape you want, place it in the middle of the ladder.
Screenshot

(You need to make sure that atleast part of the steps are outside the ladder
or a player will not be able to 'climb').

Then deintersect the stairs and add it as an invisible collision hull.
It will not be visible for the player but the ladder will and also give the
illusion that it is the ladder he is climbing and not the stairs.


BB Drac - Unreal Tournament UED2 guide BSP, Solid/Semi-Solid

Solid / Semi-Solid

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

In this 'tutorial' I will explain for you in more detail some of the
'mysteries' of brushes, BSP, collison hulls and so forth...

It seems to me that a certain 'editing' rules have grown into the
map editing community regarding intersecting/deintersecting, brush solidity
and all the "handle with care" or "this side up" warnings.

I will through this tutorial try to go in detail and play around with ideas
rather than comming with facts (if you can call it that) that really can be
questioned.

I would like to thank BitBasher (from Infogram Forums) who put big
question marks regarding the issue of Invisible Collision Hulls and its
limitation, which got me to do some 'research' regarding the entire
consept behind BSP, semi-solids and all that.

Before I start; If you know actual facts I would really like to know.
Mail me if you like, questions and corrections and all that.

Thanks to Mike G for some additional information regarding BSP problems.

 Concept, Warming up:
"Do you have a lighter?"

So where did I collect all the information from, regarding BSP?
Well, I don't really know.
Most of it came in bits and pieces from differnet sources, like sites
and people via mail and forums.
By putting all that together I have created a nice little
illusion on what is 'legal' and not.

Until this time, I have accepted that information as valid and created levels
accordingly.
But, even if I do follow all the rules and make sure that the grid is never
below 4, making sure (and even double checking) that my Invisible Collsion Hull
do not touch walls and zone portals I get BSP holes.

I accept these 'faults' as my own editing faults and curse my lack of editing
skills.

Now, to confront certain 'rules' I start defying the 'laws' of level editing
and play around with Invisible Collision Hulls, Semi-Solids, Non-Solids and
let loads of brushes overlap each other with no particular reason.

I did notice a few BSP holes, but would they be there if I followed the
above rules?

 BSP, why cutting the geometry:
"I can actually walk here."

BSP, short for Binary Space Partitioning is in simple terms a way to pre-render the
visibility in a level.

To explain BSP you would first need to know how a rendering engine, by default, work.
(Without BSP).

The easiest way to render solid geometry is to draw all polys (walls) on top of each other,
starting with the polys in the back and end up with the poly closest to the player.
As geometry can become incredible complex, rendering a screen any other way would be
almost impossible.

But, this is as you can imagen, very ressource demanding and will not render crossing
polys correct.

To make things a bit easier for the in-game rendering engine BSP will create a logical
structure of the gemoetry by calculating visibility in any given area.
(Logical structure would mean BSP tree).

What do this tell us then, and how can it help the engine?
By cutting polys into smaller parts the engine can identify the area you are located at and
make sure that you see what you should see by using a logical structure index, (read BSP tree).

In short it means that areas behind walls will not be rendered, preventing huge CPU
usage to build the display.

What is a BSP tree then?
A BSP tree is an index connecting multiple cuts together so the engine know what parts
to render, at any location and direction.

To go more indepth of BSP and what it actually do, you can take a few
look at these screen shots.
(The best way to see BSP cuts is in "Zone/Portal" view").

The first picture show all polys (sides) of a brush and they all are 'intact'.
It means that if you stand where the camera is, all polys will be visible.

In the next picture you can see a cylinder placed on the floor and it have 'caused'
the floor to be cut up in smaller parts.
Each part represent a single index in the BSP tree.
As you can see the cuts are always on the same plane as the poly.
(Plane means polys / sides that share the same axis, X Y or Z).

Logical enough, if you stand on one side of the plane you cannot see the surface of the other side.

In the last screen shot you can see that the more 'complex' geometry we create the more
complex the BSP cuts get.

All this is indexed in a 'tree'.
You can think of any set of BSP cuts as branches and sub branches where any given
BSP cut area can be located by following the branch and sub branches.

It just means that by using this system, you can prevent areas that is not visible to be
rendered as they would belong to another 'branch' in the BSP tree.

 Nodes, in addition to BSP:
"Rats, they are everywhere."

So, you want to get technical again?

Nodes is in a coders perspective almost the same as a vertex as it is used to define
a certeain geometry.
When BSP create cuts it will place nodes and draw a line between them to create a 'new'
surface.
(These surfaces cannot be textured alone or have its own flags, it's just a way
to index the BSP tree).

Actually that is it about the technical part of nodes.
Let's talk more building related, including nodes.

When you start a map you probably created a room with four walls, floor and ceiling
which would be 6 polys / sides.
If this would be just it, each time a player entered the room the rendering would simply
draw all polys on the screen.

If you put an object in the middle of the room, things become a bit different.
First of all the BSP tree would be different and the way the engine draw the polys,
all visible polys, would change.
Not only do it need to calculate how many polys you are able to see, but also how many
surfaces (BSP cuts).

With this in mind, you can imagen a very detailed room that would cause extensive
BSP cuts all over the place.
To be able to draw the correct polys on the screen the engine would have to
calculate the correct BSP cuts you have in view.

As a result, you might have guessed it, a high node count will result in
frame rate drops.

That is why we have something known as semi-solids.

 BSP Holes:
"Damn, have anyone seen my wall?"

So now that you know how the BSP tree is built, how do BSP holes fit in all this?
No code can prevent problematics like this.
Not at it's current state anyways.

When you place objects (brushes) around the level the BSP need to cut the surfaces
to get a faster rendering routine.
All this is ofcourse mathematical all the way and in the world of computers
data can only be used to a certain limit.
In this it is the limit of how many digits a decimal number can have.
If the decimal point get too far away, the particular cut in question cannot
be placed correctly in the BSP tree.

The result is a hole in the wall.
It will ofcourse only be seen in certain angles and directions as the
surface can still be successfully placed in another "branch" of this
BSP tree and therefore look normal from other angles.

 Hall Of Mirrors (HOM):
"Hey, Larry... Is that a portal?"

Hall of Mirrors, why do they occure?
Simple, you are able to see into "nothing".

It will happen when you have a wall that do not have any texture,
the texture is masked or transparet or you have BSP hole.

The engine render everything that you are able to see and if you
are able to see into nothing (which is not rendered) a copy
of the last frame will show in the area in question.

What is the "nothing" then?
This is refered to the area that you haven't any placed any solid
(added or subtracted) geometry.
This area is often said to be filled with mass, but that isn't
entierly correct but used to make understanding the add and subtract
functions easier.
The more correct term would be, the void, nothingness or limbo.

 Solids and Brush concept, CSG:
"Ouch, I hit my head."

The brush is the corner stone in creating levels with UED.
It is the clay that you shape and then add to the world,
which in the end will, possibly, end up in a playable map.

The brush can in most extreme sense have any shape and size.
But of course, when actually using and adding brushes, common sense
should apply to the result of modifying the brush.

Adding brushes to the world is somewhat incorrect as you can
both add and subtract brushes.
This is what CSG state means.
It can be either subtractive or additive as it will tell the game
if this brush should add or remove mass from the world.

If a brush is additive or subtractive can be told from the color of the
brush.
If it is yellow it is subtractive and if it is blue it is additive.

But a brush is not only limited to a CSG state.
It can also have a specific solidity.
This would be solid, semi-solid and non-solid.
(Semi-solid and non-solid explain further down).

A brush that is anything else than solid cannot be subtractive.
Meaning that you cannot subtract semi-solid or non-solids.

The color also change.
A semi-solid is pink and a non-solid is green.

When adding a brush, not by the add button but with the add special brush
button, you can change the solidity of the brush, and also other properties.

I will explain the "Add special brush" button a bit even if it will expand into
other parts.

First of all.
The prefabs you select is not a "specific" type of bush.
It is just a default selection of options in the add special brush window.
This means that "Water" and "Zone portal" is the exact same thing, but with
different options selected.
It is perfectly ok for you to change and select other options.

It also means that (which not a lot of people know) Invisible Collision Hulls
is just a semi-solid with the "Invisible" option checked.

The selections you do (except for solidity) will 'stick' with the brush.
Meaning that, trying to change this later will not work.

The add special brush is not limited to a certain shape or size of brush.
Sheets and other types of brushes will do perfectly ok.

 Semi-Solids and Invisible Collision Hulls (ICH)
"Hmmm, I can't see it, but I know it's there, somewhere."

Now that you know the concept behind brushes, understanding semi-solids
should not be any problem at all.

A semi-solid is solid as it will block players, any actors and light.
The reason it is a semi-solid is because it will not cause additional
bsp cuts.
It will not add to the current bsp tree.
This means that by adding semi-solids you will only increase the amount
of polys seen at once and not the amount of node counts.

However, a slight bi-effect comes from all this.
As the semi-solid is not part of the bsp tree (not adding to it)
it will not block the actual rendered view.
Meaning that if you would use semi-solids in windows (including invisible
collision hulls as this a semi-solid) the view the game engine render will
include everything behind it (doesn't matter if you actually see it or not).

A semi-solid can, itself, be cut by other brushes which means that it will still
be part of the bsp tree.

With this in mind you probably realize that semi-solids will only work
when using in small numbers as decoration or at special places.

The difference between ICH and other brushes?
None!
A ICH is simply a semi-solid but invisible.
Here comes another factor in.
Invisible brushes do not block light and is not affected by light either.

Why can semi-solids be a problem concerning BSP holes?
Now, as a semi-solid do not increase the amount of nodes it is not increasing the
bsp tree at all.
This means that in certain angles (semi-solids that are not straight) and
complex situtations in a given area with alot of bsp cuts it can cause the rendered
view to come out incorrect and thus causing BSP holes.

 Non-Solids:
"And I actually thought I understood."

I am not sure that I will explain anything about this topic.
I will not say anything like "Do not use non-solids what-so-ever as this will
cause major bsp holes and destroy your level..." as it will not.

But...
In what situation do you defend using non-solids?
You should always use sheets instead.

Well, non-solids will not block light but is affected by light which results in
it to look like a regular wall.
If you just must use them, use them with care and treat them as you treat semi-solids.
Use only in special places and as few as possible.

One important issue when you use both non-solid and semi-solid is to keep them
far apart.
Non-solids do not have any collision and semi-solids can cause the calculated
non-collision area to expand into areas it should not.
This will cause you to die leaving a 'crater' as you try to veture into a solid
area which no longer is solid.
The reason you get this problem is that the semi-solid, which do not affect the BSP
tree cause the collision area of the non-solid to be calculated incorrect.
(It will only happen if they are close to each other).

 Sheets and Zone Portals:
"Please, close the door, it is cold outside."

Sheets including zone portals are treated slightly different than regular brushes.
They only have 'one' poly in the sense that if you change it, it will affect
'both' sides of the sheet (including any flag you set).

With this in mind you might also see that a sheet is 0 units wide.
So in practical editing ways, changing the solidity of a sheet is useless
as it will still act the same way.
I do not know if the game engine treat sheets with different solidity
different but that is not work finding out so always use non-solid for sheets.

Zone portals are slightly different than a regular sheet as it will tell the
engine where stop add lighting and creating zones.

If you add a brush (not a sheet) as a zone portal all polys / sides of the brush
will be treated as if it was a sheet.

Sheets are always 'non-solid' and do not affect geometry so overlapping is
perfectly ok.
Sheets can not be made to block players, any actors or light.
However, the sheet is affected by light.

 The Grid, the default editing tool:
"Maybe if you put that over there?"

What is the grid?
You already know what it is and how it works,
it's the building aid you have to position, move
and align brushes more precisely inside the 'world'.

All brushes can be located (positioned) at very 'detailed' levels.
(Down to 6 decimals, x.xxxxxx)

Knowing that the grid is only an aid, why wouldn't you be able to set
the grid setting you want, or even turn it off?

To answer this you should first know what causes BSP holes.
When you add/sub brushes to the world they cut the current geometry.
When calculating these cuts the position / edges of the brush must be
included and it could cause the bsp cut / nodes to get decimal values.
There is nothing wrong with that, but a computer is only able to
handle decimal values to a certain size and then you get an error
known as "Overflow".
(The min value of a 'double float' is 2.2250738585072014 E – 308
and max 1.7976931348623158 E + 308. I don't think the engine use such
'huge' values though).

If the cut results in a decimal value that range above the valid range,
used by the engine, it will result in 'overflow' and cause BSP holes.

By thinking about this you will probably realize that the best possible way
to avoid getting decimal values is to use positions in the power of 2.

So why can't I use a grid setting below 4?
Who said you couldn't?

There is no real difference between 2 and 4 when it comes to division
Any number that result in 'endless' decimal values that you divide 4 with,
will result in the same 'problem' with 2.

Unless there is a flaw in the game engine or there actually exist a
mathematical formula that create huge gaps in the result when using
either 2 or 4 there should be no problem with a grid of 2.

But then again, it would also cause 4 and 8 to be very different,
which it really isn't.

All this should also alert you.
A brush should have the size in power of 2, to prevent the above problem.

But to turn of the grid is a whole new chapter.
First of all you would start moving it around on the decimal point (x.xxxxxx).

Division and formulas using decimal values are a pain and will often result
in more decimal digits.

Another thing that is important regarding the grid is vertex snap.
If you want to align two polys / walls of two or more brushes you should
always use vertex snap.
If not the points, polys / walls could be unaligned by a small fraction,
without you seeing it.
This again will cause the engine to calculate the cuts incorrect and cause
BSP holes.

 Brush Order, First and Last:
"No, that goes in there and that goes over there."

As you add and subtract brushes the order in which they are introduced
into the 'world' are indexed.
This is simply because when you rebuild the geometry the engine need to
'create' all brushes in the correct order, as they are indexed.

The natural order of a room and objects inside would be the room (subtracted)
first and the details (added) later.
A subtracted brush will remove all material inside its borders which means
that the brush order play and important role in how the geometry will take its
shape.

By adjusting the brush order you also adjust when the brush in question will
cut (BSP) the geometry and be cut itself.

 Deintersect and Intersect:
"Damn, I really wish I had a better knife."

First I would like to explain what these two functions really do.
They will modify the current brush to fit into the current design.
Meaning what?

Sometimes you end up having brushes that you need to add or remove
in complex situations.
The brush you have might overlap other brushes or you need a specific
type of design on the brush.
By using deintersect or intersect you can easily solve these kinds of
problems.

Deintersect will remove the parts of the brush that overlap into filled
areas while intersect remove the parts that overlap into open space.

In more realistic sense you will probably see that if you intersect a brush
around a table in a room the brush will get the exact same shape as the table.

If you would deintersect the same brush you will see that it not only "'cling"
around the table but still have the same outer size as the room.

In a more logical sense, using the same example, you see that with intersect,
which removes all parts existing in open area, will have the shape of the
table as it is 'mass' which is not removed.

The opposite, deintersect, will still have the shape of the table but simply
because the mass which the table occupy is removed from the brush.
That is also why the brush still have the same size as the room.

Another feature that this have is that all polys / sides that are cut to fit
the current geometry will receive the same texture and flags as the original
poly / side.

Meaning that if you would intersect that table from the example above
the new brush would have the same look and flags as the original brush.

This allow you to create complex objects using multiple brushes and then
intersect it to get one complex brush.

So what do all this have to do with BSP then?
Nothing really, except for the fact that a 'clean' design can prevent possible
BSP holes.

In theory there should be nothing wrong with brushes overlapping each other.
I haven't seen or heard it to be the cause of BSP holes but it sure will not
prevent it.
There is no reason for you as a designer not to keep your levels nice and tidy.

 Preventing and fixing BSP holes (and collision hulls):
"I told you not to play around with the scissors."

It almost seem that no matter what you do sooner or later a BSP hole will
find its way into your level.
That is nearly impossible to prevent.

What you do is that you focus on laying it all out to keep the chance of
getting a BSP hole reduced to a acceptable level.
If you see a BSP hole from a few nearly impossible angles when your level is
complete should be acceptable and the chance of someone finding it would
be pretty slim.

The best way to keep problems from happening to you would be to keep everything
as simple as possible and as clean as you can.
A straight wall is preferred instead of a rotated one.
Make sure that all brushes fit by using deintersect and intersect.
It might not prevent BSP holes but it sure will not add to it so there is no
reason for you not to.
Use as few semi-solids (ICH) as you can and only as decoration or at places
that you need them.
By 'planning' your level. Building it up from basic structures like rooms,
and hallways first, then add major / larger details and then start on complex
details (adding semi-solids to the end).

This might not actually prevent BSP holes from occurring but it will reduce
the chance of it.

If you have a BSP hole or even lots of them and you want them to go away,
which I think most of you would like to, what to do?
The first thing is to always rebuild the geometry and maybe change how good
the BSP should be calculated (Optimization: Lame, Good or Optimal).

By locating the actual hole and then change to zone/portal view, which
show BSP cuts, you can locate what cuts that hole is connected with.
By deleting the brush that is connected with this/these nodes the hole
might go away.

Another way is to add a brush (or subtract) close or where the bsp hole
is will cause new cuts to be made and maybe the BSP hole will be
'destroyed'.

Moving one or more brushes that is in the close area will also cause new
bsp cuts to be made and might fix the problem.

By changing the brush order of the brush(es) will make the brush cut and
be cut at an earlier or later stage.
The normal procedure here is to make the details, that most likely is the
cause of the BSP hole, have its order changed to last.

 Final thoughts:
"Seriously, why are you so angry?"

So, should you really bother with all this that I have told you?
It's really up to you!

But, as with everything else, editing levels for UT with UED2 have it's
possibilities and limits and using or abusing them will give results
accordingly.

One think to keep in mind is that it is not easy to create a fully
functional level.
You could possibly say it is like painting a picture.
There is no sport throwing colors to the canvas but creating a flowing
picture is a lot more harder.

But I think that most people need to experience the problems before they
can be dealt with.
You really don't know the limits until you have crossed the line with
huge steps.

In the end I want to say that you should not take information about BSP and
limits of the editor unless you understand the 'why' behind it.
Keep editing as you want to, but take backups at regular basis so that you
do not lose everything you have done.


BB Drac - Unreal Tournament UED2 guide Invisible Collision Hulls

Invisible Collision Hulls

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Invisible collision hulls is most often used when you want to block
players/actors from moving through specific areas.
It will block players, bullets, translocators and anything like normal walls.

If you want to use transparent or masked textures so people will be able to
see through it, but not walk/fall through it, collision hulls is the thing to use.
This might be a window or fence.
(Sheets can not be made to block players or actors).

First you create a sheet for the transparent/masked texture and
then you put the invisible collision hull behind it.

A rule with collision hulls is that it cannot touch any
wall or cross zone portals.

 Invisible Collision Hull tutorial:
Here is a small tutorial on how to use a collision hull in a "real" level.

First start with a 512x512x512 room.
Create a new room sized 256x256x256
and place it close but not connected with the first room.
The space should be 16 units in this example.

Now create a 64x64x16 and subtract it between to two rooms.
(Place it close to the floor of the second room).

Now we have two rooms and a small opening between the two.

Texture the walls and add lights.
Screenshot

Now we are going to start on the window.
Create a sheet 64x64 and AX_Xaxis.
Place this sheet in the opening between the two rooms.
Select a window texture (coret_fx.utx has two) and then press
"Add Special Brush".
Select "Transparent Window" from Prefabs and then press Ok.
Screenshot

This window will not block anything as it is now.
Actually it will never block anyting, but we will make it look
like it does when we add the collision hull.

Create a brush 63x63x4 and place it in the middle of our opening,
just behind the window sheet.
You need to change the grid to either 1 or 2 depending on how close
to the sheet you want it.

Make sure that no sides of the brush touch any sides of the wall
or the sheet.

Press the "Add Special Brush" button again but select "Invisible Collision Hull"
from Prefabs this time and press Ok.
Screenshot

Now you should see that almost the entire area is filled and with the texture
you used.
If you change to real time update this collision hull will disappear.

Place a player start and rebuild the level and try it if you like.


BB Drac - Unreal Tournament UED2 guide Complex structures

Complex Structures

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

When you start designing a level you will always come across cases
when you need complex structures.
A stair is one of them, but UED2 already have fully functional
buttons to let you create stairs in almost any shape.

Lets say you want some light hanging down from the roof.
Chains holding a small plate with a nice flame.

To do this you would need to create sheets for the chain,
more sheets for the flame and some brushes for the plate.

Instead of redo this every time and everywhere you could do this
once by creating one complex brush.

There is two good reason for this and the best is that the game engine
calculates one complex brush faster than a lot of simple ones.
The second is that editing goes a lot faster and human mistakes is kept
to a minimum.

So, this is how we do this.

First you need to create a "workspace".
This is simply a large room that is not connected to the level itself.
Subtract it a bit outside the original design and don't mind what texture
it has. It will not matter.

The complex structure you want to create you do inside here.
Here is a little screenshot of how it could be.

As you can see this arch is build using five brushes.

Now select the room that surrounds this structure and press the right mouse button.
Select "Polygons" and "To brush".
Now press the "Intersect" button and you will have "framed" your creation.
(Make sure that only the brush is selected before you intersect.)

Screenshot

This new brush can be placed anywhere you want and even the texture will be the same.

It is also important to remember that you don't need to do this any more.
Once you have added this structure somewhere in your level you only need to copy
it's polygons to the brush to create another one.

When creating movers you might want to use this method.

Don't forget to remove this "workspace" before you release the level though.

Also take a look at the 2D shape editor tutorial for more info on how to
create complex brushes.

 Importing/Exporting:
Exporting your brush is a very useful option.
After you have marked the brush, select from the menu
"Brush" and then "Export" or "Import".

Just remember that the texture you have used on the brush is saved along
with it. The texture set is not "reloaded" if you import the brush
in another map, after you have restarted the editor.


Portals

    By: Sharky
    jneta@ez-net.com

    Where to start? well first off make a basic level.. if you don't know how to do this read a basic tutorial (ill be writing one soon).. ok you have your big cube level... add your player start and some lights... next make your builder cube 200x200x200 and subtract it from a side.. next subtract from another wall (see pic1).

    The test room with the holes
    The test room with the holes Now select sheet builder set the properties to Y-Wall (or X-Wall depending on the orientation of the holes in the wall) and set the U and V to 200.. this will act as a barrier for your portal and the rest of your level.. move it in front of one of the holes in the wall (make sure its lined up perfectly).. now select a nice looking texture (i suggest picking from the GenWarp set) now that you have the texture you want hit the add special button (pic2) and use the same settings as in (pic3)...

    HIT THIS BUTTON

    USE THESE SETTINGS
    Move the builder brush to the other hole and repeat... Next go to classes and pick ZoneInfo->WarpZoneInfo and add one inside each of the holes you made... now set the properties of one of the WarpZones to Dest of Warp1 and Src of Warp2... now pick the other WarpZone and set it to Dest Warp2 and Src Warp1 (see pic4).

    The Property box (double click the ZoneInfo to pop it up)
    Now rebuild and your all set.. save your level and test it out

    The final level in UnrealED

    The level in the game, note the hall of mirrors effect (its easier to see without a texture on the sheets)


Portals 2

    By: Isolation

    The Basics

    Lets begin with a simple room, I am going to use the exact coordinates I used for my Portal map for this tutorial. The room was a 400 unit height, and 600x600 on Width and Breadth. Create the room, texture it, and throw in a PlayerStart. Now we will add two boxes. This is the space where the Portals will be. Thanks to Inoxx from the Unreal team the portal boxes HAVE to be 64x64x64 or bigger. For this little map we are making make it 200x300x200 (height*width*breadth). Put it on the outside of the room but make sure the end of it is touching the room then hit on the subtract from world button. Now let's change the brush marker to 200x200x300 this will show the same cube but now to the side. Put it on another wall and extract the world (just like the figure). One thing to remember both of the portals have to have the EXACT same geometry as the other. One CANNOT be bigger than the other. Please make sure both of your portals are done correctly.

    The Portals

    Now we will create a sheet to do this click on the button all the way on the bottom of the toolbar that looks like a gray diamond. This will change the marker to a thin sheet, now right click on the sheet button and go to Sheet Properties make the Orientation Y-Wall to make it vertical and then the U value should be 300 and the V value should be 200, hit build. Place this sheet in front of the portal that it fits and then click on the Add Special Brush button and on the PRedefined drop down list, pick Zone Portal and your portal is set. Now go to the Sheet properties and change the values from 300x200 to 200x300 and then the sheet will change direction to the other portal. Put that on the cover of the portal like the figure and hit Add Brush*. If you did it correctly it should look like the next figure. *- If you don't see anything please Rebuild geometry and if you still don't see anything make sure you added the brush.

    The WarpZone

    Now we will link the portals together. Go to the Classes menu -> Info -> ZoneInfo -> WarpZoneInfo. Add a WarpZoneInfo inside each of the boxes make sure they are in correctly at the X and Y values. Now Go to the WarpZoneInfo properties by right clicking on the WarpZoneInfo tag (it looks like a cube with a question mark) and goto WarpZoneInfo. You will see two boxes OthersideUrl and ThisTag. Double click on Othersideurl and enter the value warp1 and then double click on ThisTag and put in the value warp2. Now go to the other WarZoneInfo in the other portal and go to its properties. Do the same thing as you did with the first one but this time the Othersideurl will be Warp2 and ThisTag will be Warp1. Close the box and you are two steps away from having portals.

    Surface Properties

    Now click on one of the sheets we put in before, right click it after its been selected and go to its properties. Check Portals, 2 Sided, and Invincible. Hit close and do the same to the other one. Now to test that your portals are correct click on the joystick so that its not a shady white. When you do that the sheet brushes should not be visible instead you should see right through them and see the boxes with the WarpZoneInfo tags in them. If you do see the boxes you can check that the portals are there by clicking Mode and Zones/Portals, the whole room should be one color except the portals should be different. If this is done correctly you are almost there. Just add lights around the map and then rebuild Geometry, BSP, and Lighting. Play the map and see if it came out right.

    Mini-Portal Faq

    I click on the joystick and I see black wholes in the map.

  • Rotate the sheets so that the side that's facing the room is now facing inside the box and vice versa. It could be both sheets or just one of them. Experiment this has happened to me before and I changed the the sheets around a bit. After you do rotate it make sure you rebuild the geometry and then see if its still messed.

  • Another problem could be that the boxes aren't the same geometry I have never had this problem but you should make sure they are correct.

  • Make sure that the sheets are covering everything on the portal so you can't see inside. This could be a major problem

  • Make sure that the WarpZoneInfo entities are inside the portals boxes.

    I play the level and I have portals but they are messed up I see myself but 3 times bigger.

  • This also happened to me before, I fixed this by rotating the sheets again. If anyone knows why this even happens please email me.


Wolf's Tutorial Portals

Wolf's Tutorials: Portals (Warp Zones)

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Portals

Portals are essentially zones that not only teleport you from point A to point B, but allow you to SEE where you are going to. The portal is a "window" to another place. Since they are actually zones which "connect" the actual terminology would be Warp Zone. In this tutorial the term "Warp Zone" will refer to the portal structure. The term "portal" will refer to the actual zone sheet which is the "window" to the warp destination. You can build a simple "doorway" portal, or a much better effect is a "closet" that you can walk all the way around, or walk into and "warp" to another area (see DmRadikus).

Ingredients

For a warp zone to work you need two warp zones. The two zones have to be the exact same size and the warp zone structure can only have one portal (opening). It will actually function with two open sides, but the effect this has on the portal is weird to say the least.

Portal Structures

In this tutorial we are going to build two unattached rooms. We are going to build two portals and we will discuss some options when building portals. To start with pick a texture set and build a starting room 256 x 512 x 512. Texture it anyway you like. Now highlight the room brush, and right-click. Choose "Copy Polygons to Brush" and then deselect the room brush. Move the red brush to a another location and subtract it. You should now have two identical rooms. Change the textures in one so they don't look like alike. Now build a work room 512 x 512 x 512 off to the side. We will build the portal structure in this work room.

Now we have to decide how big our portal "closet" will be. We know our two rooms are 256 high, so it should be taller than that. Let's make the portal itself 128 x 128. Now the structure or closet this portal will sit in must be slightly larger. We want to allow for a lip of 16 units on each side, so we must make the structure 32 units larger than the portal--16 (lip) x 2(two sides)=32 units. Select the cube tool, and go to properties and size it to 160 x 160 x 160 (or 128+32). Make sure your red brush is in the middle of the work room and then add it to the world. This block is the "closet" for the portal so pick a nice texture for it. Now resize the red brush to 128 x 128 x 128 and position it so it "touches" one side of the block. See below:

Now subtract the brush. This should "hollow out" most of the block, leaving one side open. Resize the red brush so that it completely surrounds the block and then intersect it. Move the new red brush to the first room we made and place it in the center of the room. Add this brush. Now move the red brush to the center of the second room and add it.

Now we have our "closets" build we need to turn them into zones, and then warp zones. To zone them we need to add zone portals over the opening to "seal" them. Select the sheet brush tool and make it 128 x 128 (the size of the opening in the block), and then select X-wall or Y-wall depending on which way your opening faces. Now move the brush to the opening on the block of one of the portals and make sure it is centered. Leave a lip so it is not right on the edge of the opening, but a little bit back (I resized the grid to 8 units and moved it back one "snap" or 8 units).

When it covers the opening then click the Add Special Brush tool, and from the "Predefined" menu select "Zone Portal" and then add this brush. Move the red brush to the next portal (in the other room) and repeat. You can check to make sure you have the zones correct now by Rebuilding and then switching the 3D view to Zone/Portal view and making sure you have a different color inside the block.

Now that we have the portals zoned we need to define them as Warp Zones and set their properties so the warp to each other. In the Browser select Classes. Go to Info/ZoneInfo and highlight WarpZoneInfo. Put a WarpZoneInfo inside each of the portals. Go to the first WarpZoneInfo you added and open it's properties dialog. You will see a heading titled (oddly enough) "WarpZoneInfo." Expand this and look at the last two fields:

OtherSideURL --The "name" of the destination portal ThisTag --the "name" of this portal.

Name one Portal Warp1 and the other Warp2, that is set the above fields to Warp1 and Warp2 in one WarpZoneInfo and to Warp2 and Warp1 in the other. Now add some lights in each room and a player start in one. Rebuild and run the map. You should now be able to walk all around the portal structures and see from one room to the next. You should be able to walk through the portal and "warp" to the other room.

Tips:

If you should get a HOM (hall of mirrors) effect or other strangeness in your portals, try deleting the zone portal sheets, rebuilding, and then adding them in again, making sure they are lined up correctly. Portals are fairly easy to make, but can be kind of "touchy." Just remember to make the warp zones the same size and make sure the sheets are lined up correctly, and that you have the WarpZoneInfo properties correct and they should work fine.

I have included an example map with this tutorial for you to examine (incase something doesn't work right--I told you portals are touchy!).

Using what you have learned

Play around with these Portals and have fun. Try different things and see what works doesn't work. Try making different shaped portals in different locations (one that comes out near the ceiling, etc...). As always, if you have any questions e-mail me.

-Wolf

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


Reflective Surfaces

Reflective and Mirrored Surfaces

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    Forward:

    This is the third tutorial that I have done, so I guess I still have a hellova lot of work to do :)

    Abstract:

    This is a reasonably small tutorial (well at least I think it will be) that will show you how to make a surface reflectiveP>

    Assumptions:

    I am only assuming that you already know how to create a wall, floor, roof or anything that has a texture and can follow instructions... :)

    Tutorial:

    Introduction:

    The first thing to decide is where you will have reflective surfaces. I mean, you CAN have them everywhere, but there are a few guidelines to placing mirrors and reflective surfaces. These are simply here to make your level playable on something that does not resemble NASA and so that you will actually be able to see (I will explain this later)

    Where to put Reflective Surfaces:

    1. Mirrors are generally best placed on walls, as this means that anyone passing them !Should! see themselves.
    2. Partly Reflective surfaces (not mirrors, but say a marble floor with a high polish) seem to look best when they are used as a floor, as this gives a beautiful effect of reflectiveness - but not a mirror (have you ever seen a mirror on the ground?)
    3. When placing mirrors, make sure you don't place them ALL around a single area with lights in it, as they will all reflect the light, thus amplifying the light to a ridiculas level and generally SLOWING that section of the map to a ridiculas speed (completely unplayable on everything but NASA).
    4. Mirrors and reflective surfaces unfortunatley WILL slow your level down, so I would suggest that you use them sparingly - mainly for eyecandy - rather then using this as a main playing feature. :)

    Full Mirrors:

    To create a full mirror on a surface, select the surface and go into Surface properties (Right Clicking). Now check the boxes "Mirror" and "Unlit".
    1. "Mirror" will turn the texture into a mirror (Duh!) but this will also cause it to be uneffected by the lights around it, which means that it will be a black surface until something like a Blaster (the first gun, just in case...) is set off next to it. Then and ONLY then will it actually show up as a mirror to the light generated from the blast :(
    2. "Unlit" will make normal lighting effect the surface. I mean, if you have a nicely lit room, the mirror will look like a normal mirror... :)

    Partly Reflective Surfaces:

    Now we are talking floors, polished surfaces and dirty mirrors (the cool stuff that is...). Simply follow the same steps as above, but this time ALSO check the "Translucent" box under the Surface Properties. This will make the surface act like a mirror, but also allow you to see the texture that the surface is drawn with. This works VERY well for floor using the "marble" textures.

    Additional Notes on mirrors:

    Mirrors will not show up until you are in the actual game - I mean they will not show up as mirrors when looking through the 3D view of the editor... Don't worry this is perfectly normal and is there to make your editing life easier. As I said before, mirrors and partly reflective surfaces are best used sparingly, as they DO! Slow down the gameplay.


Basic Special Effects

By: Trevelyan

Presumptions:

You are an intermediate UnrealED user. This tutorial explains some tricks to adding eye candy to your maps.

Windows:

Many mappers neglect the creation of windows in a map, and implement one with an ugly effect: The transparent nature of the window, which is deintersected within a hole between 2 rooms, allows you to view through the hole at an odd angle. See the picture for an example:

Notice that you can see right through the wall and to the other side? This is caused by deintersecting the brush for the window into the hole in the wall that connects these 2 rooms. Normally this is a good thing, but by directly fusing the 2 brushes you will eliminate part of the wall and thus see through it when you make the window transparent. The solution is very simple…

Before you add the window brush, or after, select the center vertex (that little red or blue dot in the center of the selected brush) and click the resize button. (The little box that is vertically squished) Simply resize the brush so each end is slightly smaller so the 2 brushes do not meet. You will need at least 2 Ued units of space on each end. Add the brush and rebuild your geometry. It should now look something like this:

Mirrors/Reflective floors:

A very simple but convincing effect when used properly. When you right click on a surface select "mirror" to make the surface reflect its environment. Some things to know though:

Mirrors slow down computers! No computer out there can render a room that is coated with mirrors without a huge dip in their frame-rate. They are usually confusing when placed in certain locations and cause some other glitches. Do not place mirrors where they may reflect off the skybox, because this will cause some nasty HOM effects. Don't place fog near mirrors (or vice-versa) because this will cause some problems. Finally, use this effect with moderation; there is a reason you don't see this effect in any of Epic's maps.

As for the Reflective floors: Create your room. Select the floor and make that a mirror. Make a sheet that covers the floor, and is just above it. Do not build this sheet on the exact location of your original floor. Make the sheet transparent and the same texture as your floor. You should use a marble texture for your floor, as this will make a convincing effect. (Eol.utx is good for this.) Now, because your using a sheet brush, which is very grumpy with BPS errors, you should always add this effect last in your map and not change the sheet in any way afterwards. (In other words, don't put pillars and stuff on top of the sheet, or your asking for trouble!)

This is all that I can come up with for right now. Hopefully I will update this tutorial and get some more effects out for you. Until then, E-Mail me at connors@nnex.net if you have any questions. Happy mapping to ya!


Creating Glass in UnrealEd2

Creating Glass in UnrealEd2.0

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: maverick@planetunreal.com

Forward:

This may not be a rare tutorial, in fact, there are quite a few tutorials on glass in UnrealEd2.0, but I've been asked specifically to write one because of my tutorial style, and since I'm here not only to map, but to help the public, I agreed.

Abstract:

This tutorial will teach you how to make glass in UnrealEd2.0.

Assumptions:

I assume you know what the different brushes are, and how to use 'Special Brush' as well as intersecting and deintersecting.
'Advanced beginner' to 'Intermediate' should be good enough.

Tutorial:

Create a box with the dimensions of 1024x1024x1024 and subtract it using a texture that isn't too broken or contrasty. A base texture should be fine.
now, create a sheet brush 128x128 on any axis other than horizontal. Don't add it just yet, first, you must load the glass textures. The biggest package of textures with glass would be GenIn.utx.
This package has plenty of glass in it.
Select Glass2 from GenIn.utx. This will be your glass texture. Now, we need to make your window, this is quite easy.
Open the 'Add Special Brush' box, by clicking on an icon that should look like this:

When you have clicked that, a box should come up that looks something like this:

This is the Add Special window that comes up when you click 'Add Special Brush'. | f | This is a screenshot of the contents of the dropdown menu in the 'Add Special' window.

When you open it, select 'Transparent Window', then check the box that says '2-Sided'. Your window should look like this:

Once you have it set, click okay, and your window will be added. The window is now made! But is not complete, we have to finish it up by making it solid. You can walk through sheet brushes. This is what you should have now:

Now, let's make it complete.
Create a box, so that it is 128x128x8, and make it so that the sheet brush is inside of the box, like this:

Now, select a Base texture that you do not want to see in the game, I usually choose Metal2 from the NaliCast.utx texture package.
Click 'Add Special Brush, and from the dropdown window, select 'Invisible Collision Hull'. It should look like this:

Now, click okay, and a box should form around your window, like this:

Don't worry, your glass texture is still there, just covered by a brush that has a collision radius to it. Press the letter 'P' or add a playerstart to the map and play it, the box will disappear, and the glass will appear, but you won't be able to walk through the glass.

I hope this tutorial helped you on creating glass. I'll make another one soon that shows you what you can do with glass, but I've already stuffed a few hundred KB of pictures in this tutorial, no more is needed.

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


Reflective Surfaces

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: maverick@planetunreal.com

Date: December 18, 2000

Download: tut_reflectsurf.zip

Forward:

I decided to write a tutorial on how to create a mirror or a polished surface for your level.

Abstract:

This tutorial will go over how to create a reflective surface such as a mirror, polished marble, etc. This tutorial will also explain how and where and when to use them.

Assumptions:

I assume you know the basics of the editor, such as adding lights, subtracting and adding brushes, and everything else similar to that.

Tutorial:

Introduction:

Reflective surfaces can add a lot of detail and realism to your levels, increasing its visual quality as well as its gameplay if it is added properly. Let’s get started.

Creating a Mirror:

Start by creating a room that is 256x512x512 with the textures of your choice. (Preferably from the texture set SkyCity.utx, and the floor would look good as marble).

Now, select one of the walls and press F5. (Pressing F5 brings up the surface properties). Select the tab Flags and check Unlit and Reflective, your surface properties should look like this:

Rebuild and press ‘P’. This should allow you to view the reflective surfaces. You can play test it as well. (If your reflective surface does not show up in UnrealEd, then go to your advanced properties and adjust your software rendering to allow it).

Where to Place a Mirror:

Mirrors are great eye-candy if used correctly and appropriately in the right areas. Never create a level with too many mirrors or with a giant mirror that reflects a high polygonal area of the map, doing this will kill framerates like you couldn’t imagine. Instead, add mirrors in simple rooms, with maybe a little bit of complex polygonal areas that won’t decrease framerates too much.

Mirrors generally look good where you would find a mirror, in a bathroom, the mirrors on a car, in homes, in certain industrial areas, and so on.

Creating Partly Reflective Surfaces:

Start out by creating a room with the same dimensions of the last room you had, same texturing, same lighting, but no mirror.

Select the floor of the room and check Unlit, Reflective, and Translucent. Your Surface Properties should look like this:

Rebuild and test your surfaces.

There are two different options you can have for partly reflective surfaces, Translucent and Modulated.

Translucent: Surfaces are more reflective in dark areas and less reflective on lighter areas. In the editor, you can slightly see through the darker areas and see the blue graph below.

Modulated: Surfaces are more reflective in lighter areas, and less in darker. In the editor, the lighter areas are invisible until you press ‘P’, so don’t worry if you see some of the blue graph.

Where to Place Partly Reflective Surfaces:

Partly reflective surfaces can add a large amount of detail and increase visual quality much more than mirrors. Mirrors are used less, and most polished things are reflective. Just don’t go overboard with reflectivity.

Partly reflective surfaces generally go on Marble, polished tile, shiny metal, and if you take a look out your window, you will see a lot of reflective surfaces. Dirty mirrors works too.

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


Glass

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers:

How to have realistic looking glass in your level!

Forward:

These can be used to make some great effects in your levels, so i

thought you guys might like to see a tutorial on it!

Content:

Ok, so you've got a real snazzy level that just needs that little something or you want to give a sense of connectivity, or you just think it'll look damn cool to have some glass in your level. Well, this should hopefully be very helpful to you.

Anyway, lets get into it. Load up your level, or make a quick couple of rooms as test subjects. I am going to be using a little 'early 1900's street scene at night' kind've thingy. Here are a few shots just for the sake of it, so that you get the idea of why I'm putting in the glass. Meaning, it helps if the glass has a purpose. Anyway, here:

Hmm. It needs a little something. Glass windows! I'm going to add in windows on both sides of this little house/room thingy. I think it'll add just a touch of glass and make it look more realistic.

Lets get down to it shall we? The first thing you need to do is to find the place that you want the window and since this is an intermediate tutorial, i'm not going to baby you around and show you every single step of the way. But what you need to do is to make a (i'm going to use a cube brush, since it is just a straight wall) brush that is the correct size for what you want. Subtract a hole in the wall that you are using (that's if you are using a wall), where you want the glass. Here is how mine looks :

Got your hole in the wall ready? Good. There's not much left to do.

Now what you have to do is make a sheet the same height and width as the hole. Position it right in the middle of it...like so:

Then choose a nice glass texture (try Coret_FX or GenIn for a whole bunch of em), then click on the 'Add Special Button':

And select 'Transparent Window' in the Drop-Down Menu. And press Ok. Wow. Looks pretty doesn't it? Well...we're not finished yet. At the moment, its just a sheet that you can walk through, so we are going to change that. Sometimes you will only be making the windows really small and so, it wont really matter, but you should do this next step. Especially if you have a whole wall of glass or something. What we are going to do now is stop players from being able to walk and shoot through it, while still being able to use it for its primary function (to look through it!). Now get your (in my case) cube brush back by just clicking on the cube button, since none of the settings should have changed and it should still be in the correct position.

By this stage, it should be looking somewhat like this:

Now, all you have to do is go to: Add Special > 'Invisible Collision Hull'. Now, your hole will look like it's been filled up with the texture of the glass, but don't worry, it wont appear in the game. So just do a quick rebuild of your level and you're all set to play and check out your glass!

Since i cant be bothered, I'm not going to make an in-game picture of the glass in action, so here is the final result, just pretend the glass looks normal, like it would in the game :-)

Well, that's it till next time folks, i hope you've found this tutorial useful and feel free to check back at the site regularly. Tutorial suggestions are also welcome :-) Toodles!

About this tute: This tute was requested by a number of people, and it makes a lot of sense for me to listen to the people that use these tutorials 8-D

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Glass Tutorial

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

The other day I had a request about how to make a breakable glass window, and seeing as I wasn't to sure on one or two things I investigated, starting with how best to make a glass window, and then how to make it breakable etc.

Step 1a - Making the glass window

You have a number of options here.

Option 1 - A sheet
You can use a sheet to make a window, but it will not stop players or bullets
Option 2 - A semi-solid cube brush
This is almost the same as a sheet really
Option 3 - A solid cube brush (My personnel favorite)
With this option you must make sure that the brush does not touch other solid brushes else you get the HOM effect.
If you choose options 1 and 2 and you want players blocked you will have to add an invisible collision hull brush to block the player. Remember, these mustn't touch any other solid brushes as well.
Step 1b - Making a glass walkway
Obviously if you are making a walkway then it needs to be solid, so you either need to choose Option 3 above, or Options 1 or 2 with a suitable invisible collision hull. Everything else would be the same.
Step 2 - Setting the surface properties
The most important property of the surface is obvious Translucent. But I also find that setting most Glass textures to Unlit makes them show up better. For a sheet you should make sure it is 2 sided as well.
You can stop here if all you want is a glass window/walkway. The rest of the tutorial is for breakable glass.
Step 3 - Making it into a Mover

Next you should convert the brush into a mover by selecting it, copying polys to brush and then clicking the Add Mover button. Set the keyframe 0 to be where the window is, and Keyframe 1 to be somewhere well out of reach, out of the map even.

Set the Mover->MoveTime to 0. If you want the window to return at some point then set Object->InitialState to TriggerOpenTimed, else set it to TriggerToggle. If you choose TriggerOpenTimed then set Mover->StayOpenTime to 30-60 seconds.
Most importantly of all set Mover->bDamageTriggered to true and Mover->DamageThreshold to some value (5 to always break, higher for more damage needed). Then set Event->Event to bg1.
Step 4 - Place the BreakingGlass objects
BreakingGlass is found under Effects->ExplodingWall->BreakingGlass.
You can place as many BreakingGlass objects as you want, they should all have the same Tag so they are triggered when the window is hit, so set Events->Tag to bg1.
Next set Effects->bOnlyTriggerable to true, else when you shoot the BreakingGlass it will break on its own.
Next set ExplodingWall->bTranslucentGlass to true and ExplodingWall->bUnlitGlass to true.
If you want the effect to happen more than once you need to set Advanced->bNoDelete to true.
I've also discovered a 'feature' where the BreakingGlass objects block projectiles from hitting the glass window so it can help to set Collision->bCollideActors to false to stop this happening.
Step 5 - Test
That should be about it, and everything should work.
Download my Test map to see a working window. TUT-GLASS.ZIP


How to make an exploding wall in 10 easy steps

How to make Exploding Walls in 10 easy steps

(5 if you know how to make movers)

By: Jekko

What this tutorial will teach you

This tutorial will teach you how to build an Exploding Wall into a room in UnrealEd. I think that this is one of the best effects you can have in UT, especially in Assault maps.

Assumptions

That you can build a room, texture it, add lights and add a playerstart. If you already know how to make a mover, and just wish to follow the tutorial to incorporate an Exploding Wall into a level you have already built then please just make the wall you wish to have explode into a mover, put it where you want it, and follow the tutorial from step 6. I use UnrealEd version 1.0 so don't get confused if you use 2.0 and the button I tell you to press is not there. This tutorial is intented for all levels of mappers so please don't think I'm being patronising and insulting your intelligence :)

Tutorial

First subtract a room 256*512*256, texture it, and add lights and add one playerstart at one end of the room.

1. Add a wall 256*32*256 to the centre of it and texture it accordingly.

Caption: Here we see the room with the wall in the centre.

2.This part is VERY important. Right-click on your builder brush (the red one) and then click on "Reset" then "Reset scaling". If you miss this step, you will be able to walk through your wall. (Not what you want I assume)

3. Make sure that the builder brush completely surrounds the wall and click on the intersect brush button (below). You will see no change but if you have more complex walls this would cause the builder brush to wrap itself around the shape of the wall, providing it completely surrounded it. However, in this case the wall is the same shape and size of the builder brush so you see no difference).

Caption: The intersect brush button

4. Right click on the builder brush, and click "Copy polygons" then "to brush". This makes the textures copy on to the builder brush. Now if you're sure you've done everything correctly, move your builder brush out of the way and delete your wall in one of the 2D views. Then press F8, and then Rebuild Geometry.

5. Move the brush back to where the wall was, and click on the add mover button (Below)

6. So you now have your mover where you want it. Move your builder brush out of the way again and right click on the mover (the purple thing) and click on "Mover Keyframes" then on "Key 1". Then move your mover to anywhere outside the level.

7. Right click and set it back to Key 0 (Base). You will see it has jumped back to its starting position. Then right click and select "Mover properties" and set them as shown below.

Events

Event - EW1 (This is what you will call your ExplodingWall)

Mover

bDamageTriggered = TRUE (This means that shooting it will cause it to move)
bTriggerOnceOnly = TRUE ( this means the wall won't come back)
bDamageThreshold = 10.0000 (This means the even the Enforcer can blow it)
MoverEncroachType = ME_IgnoreWhenEncroach
MoveTime = 0.0000 (This means that it takes no time to move between keys so you don't see it move).

Object

InitState = TriggerOpenTimed

8. Now go to the classes menu andclick on "Effects" then on "ExplodingWall". Add this to level, in the middle of your mover by right clicking in the 3D view on the floor wher your mover is, and then clicking on "Add ExplodingWall here".

9.Go into the ExplodingWalls properties and set them thus:

Events

Tag - EW1 (This is the samee name as we put inthe veent box on the mover)

ExplodingWall

GlassParticleSize - Choose this yourself but dont make it too big or small or it will look stupid.
WallTexture - This should be your walls texture.

Caption: This is what your room should look like if you followed the whole tutorial

10. Rebuild your level and test it out (only one player if you built the room that I showed you. Have fun!

Conclusion

You should now know how to incorporate an Exploding Wall into your level. Play around with the NumWallChunks and the NumWoodChunks depending on the size of your wall, and you can add sound to the eplosion under the "Effects" menu.


Lode's Exploding Wall & Breaking Windows Tutorial

Lode's Exploding Wall & Breaking Glass Tutorial v1.1

By : Lode Vandevenne

lode@altern.org

Lode's Unreal

You can download the zipped version!

Go to Lode's Unreal Tournament Tutorials page for more tutorials.

Table of contents

  • Assumptions
  • Introduction
  • The ExplodingWall Actor
  • A basic ExplodingWall
  • All ExplodingWall Properties
  • ActivatedBy
  • Breaking Glass
  • Respawning Walls and Windows
  • Download
  • The Future
  • Contact

Assumptions

You'll need basic editor knowledge and a good knowledge of movers for this tutorial, I suggest you read Lode's All about Movers Tutorial.

Introduction

There are a lot of tutorials on breaking glass or exploding walls, but not one of them explains all the properties of the ExplodingWall or BreakingGlass classes. This one does.

The EplodingWall Actor

Open the Actor Class Browser, expand Effects and locate ExplodingWall.

The ExplodingWall Actor

This actor can create fragments, pieces and splinters of walls, glass or wood. You can choose size, texture, sound and other variables for 3 different kinds of fragments.

It creates the effect whenever it's triggered by a trigger, a mover, or any other event. In most cases, you use this in combination with a mover: the mover is the wall that will break, and when the effect happens, the wall mover goes to another keypoint, so it'll look like the wall disappeared.

But it is not the mover that creates the explosion effect, but the ExplodingWall actor does. So if you place the ExplodingWall actor 10 meters away from the mover, it will look like a wall disappearing, and 10 meters further some fragments that appear out of nothing. When you place the ExplodingWall actor inside the mover, this creates the effect as if the mover explodes.

The ExplodingWall also has the BreakingGlass extension, used for breaking windows.

A basic Exploding Wall

First make a wall. Then make a brush that looks like a hole that was shot out of a wall. Best is to use the 2D Shape editor and use Extrude. Make the hole as thick as the wall. Make sure the red brush is transformed permanently. Place the brush on the wall. Now press in this order: Intersect [image], Substract [image], and Add Mover Brush [image]. You just made the hole in the wall and added a mover in it, so the hole will be filled until the mover goes away. There should be a yellow, a purple and a red brush on the same place.

Create a hole in the wall and fill it with a mover

Place Key1 of the mover somewhere outside the map, then select Key0 again so the mover is back inside the hole.

Set Key1 of the mover to somewhere outside the map

Oped the Properties of the mover and change the following settings:

  • DamageTriggered = True: This way you will make the mover to be triggered when you shoot it.
  • bTriggerOnceOnly: Set this to True if you want the wall to be able to explode only once, or to False if you want it to "respawn" later so it can explode again. Read the section Respawning Walls for this.
  • DamageThresHold: The damage required to trigger the mover when shot. Here's a list of the damage the UT weapons create:
    enforcer: 17
    pulsegun: 72
    shockrifle: projectile 55, shot 40, superexplosion 165
    enhanced shockrifle: 1000
    ripper: razorblade 30, explosive razorblade 34 (?)
    biorifle: small glob 20, large glob 75
    rocketlauncher: rocket 75, grenade 80
    flackcannon: flakshell 70, chunk 16
    redeemer: 1000
  • MoveTime = 0. This way, the mover will go immediatly away from it's place, so it looks like the mover suddenly disappears. Otherwise the wall will slowly "slide" away.
  • Event (under Events): Set it in this example to "Wall".
  • InitialState (under Object) = TriggerOpenTimed. This is the only InitialState that works for DamageTriggered!

Add an ExplodingWall inside the mover, open its properties and change these settings under ExplodingWall:

  • BreakingSound: Set this to an explosionsound, for example Sound'UnrealShare.General.Explo1'
  • NumWallChunks: the number of chunks you want
  • NumWoodChunks: if your wall does not have any wood in it, you better set this to 0
  • WallParticleSize: the size of the particles you will get; 1 is rather small, 20 is really large
  • WallTexture: Set this to the same texture as your wall
  • Tag (in Events) = Wall (the same as the Event of the mover)
  • bOnlyTriggerAble (in Effects) = True: otherwise the effect will be able to start by shooting on the ExplodingWall actor.

Place the ExplodingWall inside the mover for the most realistic effect. When you used the correct Event and Tag, you should see a red line going from the mover to the ExplodingWall.

Place the ExplodingWall inside the mover

When you now open the map and shoot the wall, it might look like this:

The fragments fallen on the ground after shooting the wall

If you have bOnlyTriggerAble = True and you find out that you can not activate the mover if you shoot in the middle of it, then the ExplodingWall is in the way and blocks your shot! The solution is to set all the Collision to False in the Collision settings of the ExplodingWall.

All ExplodingWall Properties

In the previous section, you only used a few settings necessary in that particular situation. Here's a list of all the proporties and an explenation. As you can see, there are 3 differend kinds of particles that can be casted, all at the same time. For every kind of particle you can choose a size and a texture. If you have a brick wall with a window in it and also some wood, you can use them all at the same time.

Effects
bOnlyTriggerable | If this is False, the explosion will be able to be started by two things: If the BreakingGlass actor is triggered by an event called by a trigger, a mover or whatever, OR if you shoot at the BreakingGlass actor with any weapon. If this setting is set to True, it can only be triggered by the event, and not by the weapon. This does not work with the normal ExplodingWall actor.
EffectSound1 | These don't seem to work
EffectSound2
ExplodingWall
ActivatedBy | This is explained in the section "ActivatedBy"
BreakingSound | The sound that will be played when the explosion starts
bTranslucentGlass | If True, the GlassChunks will be translucent
bUnlitGlass | If True, the GlassChunks will be unlit
ExplosionDimensions | This is how the radius of the explosion itself: all the particles will start somewhere inside this radius. This is the radius of a sphere around the ExplodingWall actor.
ExplosionSize | This is how fast the particles will fly and thus how far they'll fly away from the origin.
GlassParticleSize | The size of the Glass Particles. 1 is normal, 10 is really large
GlassTexture | The texture of the Glass Particles; set this to the same texture as the glass or window that breaks
Health | This is explained in the section "ActivatedBy"
NumGlassChunks | The number of Glass, Wall or Wood Particles that will appear. Note that in reality the number of them will not always be the same, and most of the time much less.
NumWallChunks
NumWoodChunks
WallParticleSize | The size of the Wall Particles
WallTexture | Set this the texture of the wall that explodes, to make it most realistic
WoodParticleSize | The size of the Wood Particles
WoodTexture | Set this the texture of the wall that explodes, to make it most realistic. If you set no texture, a default wood texture will be used

ActivatedBy

Thanks to 32_Pistoleta who figured this out and sent this list!

In ActivatedBy, you can fill in names of DamageTypes. If you fill another name than exploded in here, the ExplodingWall will ONLY be activated by the DamageType you entered. The DamageTypes are caused by specific weapons, here's the list of all the weapons responsible for every kind of DamageType:

  • ImpactHammer
    impact: Primary fire, Secondary fire
  • Enforcer/Double Enforcer
    shot: Primary fire, Secondary fire
  • ShockRifle
    jolted: Primary fire, Secondary fire, Combo
  • PulseGun
    Pulsed: Primary fire
    zapped: Secondary fire
  • ChainSaw
    slashed: Primary fire
    Decapitated: Secondary fire
  • Bio Rifle
    corroded: Primary fire, Secondary fire
  • Ripper
    shredded: Primary fire
    RipperAltDeath: Secondary fire
  • Minigun
    shot: Primary fire, Secondary fire
  • Flak Cannon
    shredded: Primary fire
    FlakDeath: Secondary fire
  • Rocket Launcher
    RocketDeath: Primary fire
    GrenadeDeath: Secondary fire
  • Sniper Rifle
    shot: Primary fire, Secondary fire
  • Redeemer
    RedeemerDeath: Primary fire, Secondary fire

Make sure bOnlyTriggerable is False and the mover does NOT have an Event, otherwise you can still activate it with any weapon if you shoot the mover! Instead, give the ExplodingWall the Event to activate the mover, and set the InitialState of the mover to TriggerOpenTimed.

So, if you want your wall to explode only by the shockrifle, just input the string 'jolted' in ActivatedBy.

With the Health setting you can give the ExplodingWall a certain health, so you need several shots before it Explodes. The list of what weapon gives what damage is in the section "A Basic Exploding Wall".

Breaking Glass

The BreakingGlass actor is an extension to the ExplodingWall, and has a few more options, in BreakingGlass: Numparticles and ParticleSize.

These 2 options replace the NumGlassChunks and GlassParticleSize settings of the ExplodingWall. You can make a breaking glass effect with the ExplodingWall as well, but the BreakingGlass has some settings already prepared for you, for example the sound and explosionsize.

For the sound, texture, unlit and translucenty settings, you have to use the same properties as the ExplodingWall.

To make the window, first make the gap in the wall, and then use a mover that is one unit thick, with translucent surfaces. You can of course use a sheet, but sheets don't block players unless you use an invisible collision hull, which means you have got to use two brushes instead of one. Apply the same properties to the mover as for the exploding wall explained in the beginning of this tutorial.

When you have this and rebuild, you see that the light does not go through the window. To make the light go through the window, open the properties of the mover, expand Mover and set WorldRayTraceKey to 1. Now the light will be calculated as if the brush of the window is at it's second key, outside the map, and the light will go through it!

Add the BreakingGlass actor, give it the correct Tag, and apply all other necessary properties like the ExplodingWall in the beginning of the tutorial. It's best to set bUnlitGlass and bTranslucentGlass to True, for the best effect.

Respawning Walls and Windows

In multiplayer maps, you may want to have these exploding walls or windows to respawn so other players will be able to shoot it again. To do this, change the following properties:

In the properties BreakingGlass or ExplodingWall actor, in "Advanced":
-Set bNoDelete to True. That way the actor will not be destroyed after it has done it's job, and can do it everytime again if it's triggered.
-bOnlyTriggerable = True. Otherwise players will be able to activate the effect over and over by just shooting on it, even if the wall or windowmover is away.

In the properties of the mover, under "Mover":
-bTriggerOnlyOnce = False
-Set StayOpenTime to the time you want the wall or window wait before it "respawns"

Download

break.zip

The Future

I WILL update this tutorial

If you have any ideas, problems, suggestions, questions or have discovered a mistake, don't hesitate to contact me! Thanks a lot.

Contact

my email adress is: hybrid6666@yahoo.com

Copyright ©2000-2001, Lode Vandevenne

Please do not upload this tutorial to any site, only make a link to http://www.planetunreal.com/lode/ . Otherwise older versions keep hanging around on the net.


Smashing windows

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : Window.UNR

This tutorial will help you create a window that bars the players path until it is shot at, at which point the window will appear to smash to pieces.
Tutorials you will need to have read are: MOVERS

1) Create a hole in the shape of the window you want in your room.

2) In a box somewhere off your map create a block slightly smaller than the size of the window you want (by about 4 units), select all the textures for it, bring up the texture properties (F5) and click the invisible box. (This is the part that will stop the player walking through it which we will call the collision wall).

3) Create a sheet also slightly smaller than the gap you want for your window, and place it just in front of your block. (A sheet the same size can cause strange HOM effects when they touch the sides) and use a glass texture (from GenLN.utx) Make it transparent (from properties again), and possibly unlit too (fiddle to get the best look).

4) Intersect these (place your red brush so it envelopes both the new brushes).

5) Now following this example of the mover's properties, give it an event of "boom".
Set bDamageTriggered to true.
Set bTriggerOnceOnly to true.
Set the move time to 0 so that the player won't see it happen.
Set it to Trigger Toggle in its initial state.

6) Set keyframe1 to somewhere way underneath your map so that its well out of the way.

7) Now to add the effect of broken glass you need to add the "BreakingGlass" actor to your map which you will find under effects/exploding wall in the actor browser. Place it in a central position in front of the window call it "boom" in its tag field so that the mover will trigger the effect of glass smashing.

8) Under the "effects" property of the breaking glass actor, set it "bOnlyTriggerable" to true to make sure that the glass won't smash without the window actually moving. You should also set the collision radius of the breaking glass actor to something small like 5 high and 5 radius so that it won't get in the way when you fire.

8) Now all you need to do is try it out!


Smashing Windows

Exploding Walls

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : ExplodingWall.UNR

As with a lot of effects in level design, an exploding wall is actually an illusion. It is created by creating a hole, and filling it with a block that moves away instantly and triggers off shrapnel to make it look as if it has blown up. Here’s how it's done.
Tutorials you will need to have read are: Triggers, Movers

1) First create a room say 1024 x 1024 x 1024 in size with the usual lighting, player start and SinglePlayer game info in the level properties). We’re going to blow a chunk out of it.

2) Now, you need to create an irregular shape which will be your hole after the damage has happened. For this, you can either use the 2D editor to create a jagged shape, or use the sphere brush. Turn and rotate your brush and have half of it inside the wall, this will give it an irregular looking shape.

3) Now hit the intersect icon and it will flatten itself against your wall. Now hit the subtract icon and your hole will appear in the wall. Texture the hole any way you like, but a base texture will probably look best. Now hit the mover icon and the whole will be filled perfectly with a mover. When the level is running, the wall should look just the same as it would without the hole there but possible with a slight color difference. (note: If you want the player to have a hint that this needs to be shot at, you can alter the position of the mover ever so slightly to reveal a tiny crack in the wall).

4) Now we need to tell the mover how to act. Bring up its properties and open out the “mover” property. In the “Movetime” field change it to 0 so that the move is instant and cannot be seen. Under the “Object” property pick the “Initial state” field and choose “Trigger Toggle” Now set its first keyframe to 1 and move it so that it is completely off the level. Make sure that the route it takes doesn’t have to go through your player, this may do strange things! (Don’t forget to reset it back to keyfram0). Lastly set the mover’s event field to “Boom” and its tag to “Bang”.

5) Now we need to add an “effect” to create some exploding shrapnel. To make this choose “Effects” from your list of actors and find “Exploding wall” amongst them. Add this to your room roughly in the middle of your hole, just in front of the wall.

6) Now bring up the exploding wall’s properties and label the tag “boom”, that will cause the explosion to happen as soon as the mover has been triggered. Now look in the “exploding wall” property, choose the texture from the texture menu that matches your wall and click on “use” in the “Wall texture”. Also make sure that Effects/btriggeronly only is set to true so that it won’t go off when you don’t want it too. All the other settings there can be adjusted to your preference.

7) Lastly we need to add a trigger to set it all off. (Note: We could set the mover to be “damage triggered” so that it moves when the player shoots at it, we covered this in the smashing window tutorial). From the actors browser, choose trigger. (It must be the one that looks like a switch and not a camel’s head!) add the trigger in about the same place as the exploding wall actor.

8) Set the trigger’s event field to “Bang”. When the trigger is triggered it will move the mover and the mover will trigger the explosion. But we want the trigger to be triggered when you shoot at it and not when you touch it. To do this bring up the trigger’s “Trigger” property and under “Trigger type” choose “TT_Shoot”. Also set the trigger property “btriggeronceonly” to true.

9) You also need to set the collision radius for the trigger so that its big enough to detect if you’ve actually shot the point you want. You’ll need to be able to see the radius of your trigger to do this so you’ll need to change your display windows in the 2D views. Right click on the grey part of the menu bar of the top down 2D window and choose actors/radii view. When you click on the trigger you should now see a blue circle around it. That’s the collision radius of the trigger. For this purpose you’re interested in the height of the trigger so do the same in the menu bar for either your x or y axis 2D window. The radius there will appear as a red square. It probably won’t be high enough. To change the collision height and radius of the trigger simply experiment with the figures in the trigger’s “Collision” property fields.

10) And that’s it. When you’re ready, rebuild the level and test it. The wall should blow up when you shoot at it.


Smashing Windows

Falling Girders

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : Girders.UNR

Tutorials you will need to have read are: Movers

For this effect a similar method will be used as the exploding wall, so you may want to refer to that too. You may have to fiddle with this to get it to look just right, but the principle is sound. Explosions and other special effects can also be added to improve the feel of the event.

1) First create a room say 1024 x 1024 x 1024 in size.

2) Now, you need to create a long bar to look like your girder. Intersect it and place it as a mover on the ceiling of your room.

3) Now we need to tell the mover how to act. Bring up its properties and open out the “mover” property. In the “Movetime” field change it to .3 so that the girder will drop very quickly.
Under the “Object” property pick the “Initial state” field and choose “Trigger Toggle”.
Now set its first key frame to 1, select a corner vertex of the mover that is touching the ceiling and rotate it so that one end is still on the ceiling and the other end is on the floor.
Now change the key frame to 2 and move the girder so that the edge that was on the ceiling is now on the floor and the other edge that was on the floor lift up just slightly.
Set the key frame to 3 and place the girder into its final fallen state. (Don’t forget to reset it back to keyfram0 when you’re finished).
Choose some suitable crashing sounds and place them in the mover sounds section (there are some good ones in "DoorsAnc”.
Also set the “Numkeys” field to 4 in the “Mover” properties.
Lastly set the mover’s tag to “Crash”. You will aslo need to set the mover to crush, or stop when encroached, depending on how much harm you want to do to your player. If you choose “stop” make sure you place a damage value in the “encroach damage” field.
It will also need to be set to "Move by time" too.

4) Lastly we need to add a trigger to drop our girder. (Note: We could set the mover to be “damage triggered” so that it moves when the player shoots at it, but this can be erratic depending on where the focal point is for your mover brush). From the actor class browser, choose trigger. (It must be the one that looks like a switch and not a camel’s head!) add the trigger on the floor a few steps behind where the girder will fall.

5) Now set the trigger’s btriggeronceonly field to true and set its event field to “Crash”. When your player walks over the trigger, your girder should drop from the ceiling in front of them.


Effects Class Reference

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Tutorial Files
Tut-Explosions.zip
Introduction

Firstly I should point out that there are a very large number of effects listed in Unreal and Unreal Tournament, and to list them all here as I have in other referencese would make this document unmanagable. Therefore I shall only be listing those that I think are of interest to level editors. If you disagree with any of my selections or would like any others you think are of particular interest covered then feel free to let me know.

\-Blacksway-\

You will find that a lot of Effects, if simply placed in a map do not appear in game. There are 2 reasons for this. The first you cannot do anything about, often in the code there is a line which says Destroy(). If that is there (often called after the last animation has been run) then it will always disappear. However if you cannot find such a line then check the value of Advanced->LifeSpan and try setting it to 0. I will list some of the effects which can be useful in this manner below, e.g. MercFlare.

Contents

UT: Unreal Tournament only

BoulderSpawner | Bubble | ExplodingWall | BreakingGlass | ExplosionChain | MercFlare | MortarSpawner | SmokeGenerator | ShortSmokeGen | SmokeHose | Sparks | UT_ShortSmokeGen

BoulderSpawner: UT

This spews forth catapult boulders each time it is triggers. The boulders have the direction of the BoulderSpawner and have the speed from the BoulderSpeed property. Values of 5 - 30 would probably be a good place to start.

No other properties are used.

Parameters

BoulderSpeed

The velocity of the released boulder

[^TOP]
Bubble
Underwater bubbles - used by the BubbleGenerator found under decorations.
[^TOP]
ExplodingWall

The exploding wall is the effect that you place next to a wall which you want to blow up.

The usual way of using this effect is to have it triggered when the mover is damaged. For this you need to set the DamageTriggered to true and DamageThreshold to something greater than 0 for the mover in question.

If you want the ExplodingWall itself to be damaged then set the Health and the ActivatedBy array values ("all" for any damage). Check below for a list of damage types.

Check out the tutorial map for an example of this class.

Parameters

ExplosionSize

Effects the velocity of the particles produced.

ExplosionDimensions

Effects the volume of the space in which particles are created.

WallParticleSize

The size of the wall chunks that are created.

WoodParticleSize

The size of the wood chunks that are created.

GlassParticleSize

The size of the glass chunks that are created.

NumWallChunks

The number of wall chunks to create.

NumWoodChunks

The number of wood chunks to create.

NumGlassChunks

The number of glass chunks to create.

WallTexture

The texture to be applied to the wall chunks.

WoodTexture

The texture to be applied to the wood chunks.

GlassTexture

The texture to be applied to the glass chunks.

Health

If it is to be activated by shooting then set this to the amount of damage it must sustain before exploding.

ActivatedBy[5]

An array of 5 strings signifying the damage types that will damage the exploding wall. See Notes below for a list of which weapons do what type of damage.

BreakingSound

The sound to play when the wall breaks.

bTranslucentGlass

Should the glass fragments be translucent, i.e. see through.

bUnlitGlass

Should the glass fragments be unlit. Generally I would set this to true as the glass shows up better. However if it was meant to be really thin glass then false might be more realistic.

Notes

The values for different weapons that you can use in the ActivatedBy array:

ImpactHammer = "impact"

Chainsaw = "slashed" or "Decapitated"

Enforcer = "shot"

Plasma Rifle - 1st Fire = "zapped"

Plasma Rifle - Alt Fire = "Pulsed"

Minigun = "shot"

Razor = "decapitated" or "shredded"

Razer - Alt Fire = "RipperAltDeath"

ShockRifle = "jolted"

Biogel = "Corroded"

SniperRifle = "shot"

Redeemer = "RedeemerDeath"

FlakCannon - 1st Fire = "shredded"

FlakCannon - Alt Fire = "FlakDeath"

Rocket = "RocketDeath"

Grenade = "GrenadeDeath"

Cannon Shot = "burned"

[^TOP]
BreakingGlass
Exactly the same as above, but with different default settings. The default settings for this one are funnily enough more glass orientated.
[^TOP]
ExplosionChain

This creates a wonderful explosion effect and sound.

Can either be triggered or hit with damage (don't forget to change Effects->bOnlyTriggerable to false and collision details appropriately.

Check outhe tutorial map for an example of this class.

Parameters

MomentumTransfer

If you are caught in the blast are you blown backwards? Well leave this at its default and you will be. However if you want some kind of nuclear wind effect then you could reduce it.

Damage

The amount of damage done by the explosion. Sends out a HurtRadius with a damage type of 'detonated' (which will detonate other ExplosionChains btw). The radius of the hurt is dependant on the value of Damage.

Size

A multiplier for the size of the explosion sprite (but not the actual damage). The true size is random but based on Damage and multiplied by Size.

DelayTime

The delay from triggering until detonation, don't know why but setting it to 0 stops the damn thing working. Try a really small value like 0.1 and use a dispatcher to control other things correctly.

[^TOP]
MercFlare
At first I thought was completely useless, but after setting Advanced->LifeSpan to 0 it stays in the level and looks like a very cool light orb, giving a lovely orangey hue (you can obviously change this!) Look out for this used ALOT in any maps I ever make from now on!
[^TOP]
MortarSpawner: UT
This produces mortar shells, at a regular interval. They point in the direction of the spawner, but when they hit they produce a blast effect similar to the above ExplosionChain.
Properties

ShellDamage

Amount of damage done by the explosion.

ShellMomentumTransfer

The momentum transferred by the explosion.

ShellBlastRadius

The radius of the blast damage.

RateOfFire

Number of seconds between shell launches.

ShellSpeed

The velocity of the shells produced.

Deviation

Deviation in standard Unreal angles, which means the default of 4096 is 45 degrees.

bDeviate

Does the angle deviate (all 3 axis are deviated by a random value based on the above angle (between 0 and Deviation).

FireSound

The sound to play when the mortar is fired.

[^TOP]
SmokeGenerator

First off, this has to be triggered, I've heard loads of people asking why it doesn't work and they haven't got it triggered right. Its one of those complicated ones that when you Trigger it it starts and when you UnTrigger is it stops. Now you may ask, what the hell Untriggers something, well the answer is lots of the triggers actually untrigger after they have finished. The basic trigger triggers when you move inside the collision radius and untriggers when you move out. So beware.

Everything else is pretty self explanatory (so I'll explain it anyway!)

There are a number of different ways you can use the generator.

1. Smoke when triggered and stop when untriggered: set TotalNumPuffs to 0. If you want it to be triggerable again then set bRepeating to true.

2. Smoke when triggered for a certain number of puffs: set TotalNumPuffs to something other than 0. Again if you want it to be triggerable again then set bRepeating to true.

To get it to smoke continuously then you need to use a trigger which doesn't untrigger, such as a dispatcher and set TotalNumPuffs to 0.

Check out the tutorial map for an example of this class.

Properties

SmokeDelay

Delay in seconds between smoke puffs (although it is randomised slightly). Must be larger than 0.

SizeVariance

A variance added to the size of the smoke puffs.

BasePuffSize

The base size of the puffs. e.g. BasePuffSize of 1 and SizeVariance of 2 would give puffs ranging between 1 and 3. (This "Size" is actually the scale of the smoke puff sprite)

TotalNumPuffs

The total number of puffs of smoke to release.

RisingVelocity

The velocity of the rising smoke.

GenerationType

The class of smoke puff the spawn.

bRepeating

Is the triggering repeatable or is the generator destroyed after completeing its first cycle.

[^TOP]
ShortSmokeGen

Exactly the same as above but cannot be triggered, it starts at play beginning and either does TotalNumPuffs then stops or if TotalNumPuffs is 0 it goes on forever.

There is also a UT_ShortShokeGen, see later..

No Properties
[^TOP]
SmokeHose

This is very similar to the smoke generator except for 2 things.

Firstly the smoke puffs are sent out in the direction of a corresponding SmokeHoseDest actor with the same Tag as this actors Event.

Secondly the hose is either initially active, or is triggered/untriggered on/off. Note if it is initially active you can still set it to be untriggered off.

Properties

bInitiallyActive

Is the smoke hose initially active, i.e. churning on startup.

SmokeSpeed

The velocity of the smoke puffs

SmokeAccel

The acceleration of the smoke pufss (in terms of X, Y and Z axis).

SmokeDelay

Base delay between smoke puff generation.

SmokeDelayVariance

Variation in delay between smoke puff generations.

SpeedVariance

Varaition on initial speed of smoke puffs

BasePuffSize

Basic puff size.

SizeVariance

How much the size varies.

TotalNumPuffs

Total number of puffs to be spawned before stopping, note setting to 0 does not mean it goes on forever.

[^TOP]
Sparks

This is actually a spark generator, and it produces 'sets' of sparks at random intervals.

Having said all of that I'm not 100% sure what a 'spark' looks like, all I can seem to get is a funny light pattern on the floor!

Properties

MinBetweenTime

Miniumum time between spawning sets of sparks

MaxBetweenTime

Maximum time between spawning sets of sparks

MinSpawnedAtOnce

The minimum number of sparks in a set

MaxSpawnedAtOnce

THe maximum number of spawrks in a set

MinSpawnSpeed

The minimum velocity for each spark

MaxSPawnSpeed

The maximum velocity for each spark

MinBurnTime

The minumum time before each spark burns out

MaxBurnTime

The maximum time before each spark burns out

MinBrightness

The minimum intial brightness of the sparks

MaxBrightness

The maximum initial brightness of the sparks

SpawnCenterDir

The direction new sparks fly

AngularDeviation

Angluar deviation (for pitch and yaw) that sparks can range from the directional center above.

[^TOP]
UT_ShortSmokeGen: UT
This is a combination of the SmokeGenerator and the ShortSmokeGen as it is always active upon startup, but can then be triggered/untriggered to change its state. It will destroy itself if it ever reaches its limit of TotalNumPuffs within one trigger period or you can set TotalNumPuffs to 0 for an infinite effect.
Properties
I could list all the properties and explain them again, but they are identical to the above smoke generators.
[^TOP]


KeyPoint Class Reference

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Introduction

This is a descriptive list of the KeyPoint actor class within the unreal script class structure. It is intended as a reference for level editors and is not intended for programmers or mod developers. However they may find it of some use, you never know.

The KeyPoint classes are used to mark specific places in a level and provide further actions or properties to that place.

Some of these classes are of no use to level editors at all, and will be covered very lightly. For some others, only the parent classes will be dealt with and these features should apply to all their children classes.

Quick Guide to acronyms and icons

UT: Unreal Tournament only

: Useful to level editors

AmbientSound | BlockAll | BlockMonster | BlockPlayer | DynamicAmbientSound | EarthQuake | CH_Earthquake | InterpolationPoint | LocationID | MakeNaliFriendly | ObjectPath | PathPoint | RockSlide | SpectatorCam | QuakeCam | ThingFactory | CreatureFactory | ThrowStuff | TriggeredAmbientSound

: Some interest to level editors

GuardPoint | HoldSpot

: No interest to level editors, don't even bother, I know I wish I hadn't

OEMEnd

AmbientSound:
Sits their and emits a sound. No different from placing any other actor in a level and setting its ambient sound
[^TOP]
BlockAll:

Simply put, this actor blocks all actors (in much the same way as a wall does, but it cannot be seem when playing.) Used by Epic stop bots try to get to unreachable places, (e.g. through floor grates etc.)

These three keypoints use the following properties to affect different types of objects.

bCollideActors:

Blocks projectiles etc.

bBlockActors:

Blocks monsters

bBlockPlayers:

Blocks players and bots

[^TOP]
BlockMonster:
BlockMonsters prevents monsters from passing, but allows players and projectiles to cross.
[^TOP]
BlockPlayer:
BlockPlayers prevents players from passing, but allows monsters and projectiles to cross.
[^TOP]
DynamicAmbientSound:

Randomlly plays one of a number of different sounds. You can specify a probability the likelyhood of a sound playing next 'round'.

Every n seconds, where n is a random time between minReCheckTime and maxReCheckTime it will check the playProbability, and if true then it will play one of however many sounds you have specified.

Parameters

bInitiallyOn:

Will play a random sound on startup if true

Sounds[16]:

The sounds to play

playProbability:

The probability of playing a sound each 'round' (between 0 and 1, default is 0.6)

minReCheckTime:

The minimum time between 'rounds'

maxReCheckTime:

The maximum time between 'rounds'

bDontRepeat:

Never play a sound twice in a row.

[^TOP]
EarthQuake:

This will shake and throw players on a level. This makes their HUD shake and can optionally move tha player about as well.

Parameters

magnitude:

The amount to shake the player by, default is 2000

duration:

duration for earthquake, default is 5 seconds

radius:

radius for those players to be affected by the earthquake

bThrowPlayer:

Does the earthquake move the player as well (throws them from side to side etc.)

[^TOP]
CH_Earthquake: UT:
Much the same as EarthQuake, but uses a more efficient algorithm for checking to see if players are affects, and will also throw pushable objects (barrels etc) around if bThrowStuff is set to true. This is the only parameter that is different from the above EarthQuake.
[^TOP]
GuardPoint:
This is created when a monster is set to guard a particular object. You set 'Orders' to "Guarding" and set the 'OrderTag' to the tag of the object to be guarded. You shouldn't place this in your levels.
[^TOP]
HoldSpot: UT:
This is created when you issue the 'Hold' command to bots in Unreal Tournament. You shouldn't got placing this in your levels.
[^TOP]
InterpolationPoint:

Ooh, complicated. Put basically they are used for creating a path for a kind of movie fly-by effect. They are used in the start-game castle fly-by at the start of Unreal and the start-game intro in Unreal Tournament. But enough about that, lets get down and dirty…

First thing to do is create a SpecialEvent with initial state "PlayerPath". Set its Event to "Int1" for example. Next create a number of InterpolationPoint's with tags of "Int1" and set their Position values from 0 to the whatever. Set one of the InterpolationPoint's bEndPath to true (presumably the last one!). Then when the SpecialEvent is triggered the player should get a fly-by rush. I really must test this!

Half the other properties aren't used anywhere, so I don't know why they are there. Who knows.

[^TOP]
LocationID:

Marks and names an area in a Zone. These can be used when you want area descriptions to appear (say in team matches in the chat screen) bu don't want to split you level up into little zones.

Simply place the LocationID in your level, set its Radius and the LocationName.

[^TOP]
MakeNaliFriendly:

Should really be in the 'Triggers' section, but hey, who am I to complain.

When triggered makes all Nali in the level friendly to the player (even if you've blown their friends to little bits of Nali Chunks!)

[^TOP]
ObjectPath:

Allows you to move an actor. Set the tag of the actor to be moved to the same as the PathActorTag property. Then place a number of PathPoints with the same tag as the ObjectPath actor. These define the path to be taken by the actor object. Then when the ObjectPath is triggered the object is moved to the first PathPoint and then allong the path (using lots of complicated curving algorithms that I couldn't be arsed to work out).

Parameters

PathActorTag:

Tag of the actor to be moved

bAlterPitch:

Does the pitch of the actor change as it moves along

bAlterYaw:

Does the yaw of the actor change as it moves along

bAlterRoll:

Does the roll of the actor change as it moves along. Use all three for a kind of airplane effect

RAdjust:

Adjust the rotation of the actor as it moves along.

[^TOP]
OEMEnd:
Err, presumably used at the end of Unreal somewhere. Don't have Unreal on this computer so I can't tell you.
[^TOP]
PathPoint:

See above ObjectPath for more details.

Parameters

sequence_Number:

To order the path points

curveSpeed:

how fast the object must move at this point (affects shape of path, not really speed)

speedU:

speed factor, a value of 1 will travel through the segment in 1 second, 0 stop, 2 in 1/2 second, etc..

[^TOP]
RockSlide:

This would appear to create a rock slide, hey, what will these epic guys think of next…

It spawns rocks within the CubeDimensions of the RockSlides location you specify. It will continue till TimeLength is reached or forever if TimeLimit is false.

As noted in the code, the rocks aren't currently doing a lot, so let them fall a distance to do more damage.

Parameters

CubeDimensions:

vector of the dimensions of the space to create the rocks in.

TimeLimit:

if false will continue for ever.

TimeLength:

the amount of time till no more rocks are created from when it is triggered.

MinBetweenTime:

Minimum time between rocks

MaxBetweenTime:

Maximum time between rocks

MinScaleFactor:

Minimum scale factor of the rocks (1 is normal etc)

MaxScaleFactor:

Maximum scale factor of the rocks

InitialDirection:

The initial rotation of the rock

minInitialSpeed:

the minimum initial speed

maxInitialSpeed:

the maximum initial speed

[^TOP]
SpectatorCam: UT:

Simply put, this is a camera position which is placed in the game. It is used if someone starts the game as a spectator, and also for those end of game sequences in the Assault maps.

Parameters

bSkipView:

If being used by player as a spectator, then should they skip this camera.

FadeOutTime:

The time to fade when used as a end game camera.

[^TOP]
QuakeCam: UT:

Identical to the SpectatorCam, except is also shakes the view of the player

Parameters

magnitude:

The magnitude of the shakes, defaults to 2000.

[^TOP]
ThingFactory:
Simply put the thing factory creates things. You place a ThingFactory somewhere on your map, and a number of SpawnPoints (See NavigationPoint Ref). Set up the factory with a prototype and the maxitems and capacity for the factory. When the ThingFactory is triggered it should start spawning things at the various SpawnPoints.
Parameters

prototype:

The class of the thing to spawn.

maxitems:

The maximum number of current objects allowed in existence at once.

capacity:

The total number of objects this factory will spawn in its lifetime.

interval:

interval in seconds between spawning, altered by timeDistribution below

itemtag:

A tag to apply to any spawned objects, defaults to 'MadeInUSA', those crazie Epic guys!

bFalling:

Whether the object created is initially set into a falling physical state.

timeDistribution:

One of: Constant, time between each creation is the same; Uniform, time between spawnings is between 0 and 2*interval; Gaussian, some kind of ultra random range between 0 and 2* interval.

bOnlyPlayerTouched:

If triggered by touch (determined largely by where you put the damn thing) only trigger from the player, not monsters.

bConvert:

If true, then only spawn at a spawnpoint which the player cannot see, if players can see them all then no object is spawned.

bStoppable:

Stops spawning if the thing factory is untouched (i.e. the player walks away)

[^TOP]
CreatureFactory:

The same as ThingFactory above, but allows you to assign orders to creatures that are spawned.

See Unreal AI reference for patrol points and guard points for the purpose of Orders etc.

Parameters

Orders:

See above reference, but you may wish to for example set the Orders property to Ambush, set the OrderTag to the value of a AmbushPoint and then the creature will move to this AmbushPoint upon creation.

OrderTag:

Used in conjunction with the Orders value above.

AlarmTag:

The tag of the AlarmPoint the creature should attempt to reach when they see the player.

AddedCoopCapacity:

If the game type is CoopGame then add the capacity of the creature factory is increased by this amount.

[^TOP]
ThrowStuff:
This will throw all pushable objects in a given or random direction.
Parameters

throwVect:

The velocity vector to throw the objects, or used as the basis for the random direction if bRandomize is true.

bRandomize:

If true then the above throwVect is randomized. The vertical direction is always maintained (i.e. if throwVect is in a upwardly direction then so will the new random vector)

interval:

Time between throws.

Numthrows:

The number of throws. Defaults to 1.

[^TOP]
TriggeredAmbientSound:

While on this will replay a sound using the values set below.

This has 2 states, either TriggerToggled or OnWhileTriggered.

If TriggerToggled then each time it is triggered it is turned either on or off.

If OnWhileTriggered then it will be on while triggered and off while not triggered.

Parameters

bInitiallyOn:

If true then the sound is played as soon as the level starts.

AmbSound:

The sound to play.

rePlayTime:

The minimum time between replays of the sound.

rePlayVariance:

A random variation of this size to when the sound replays.

bPlayOnceOnly:

Should the sound be only played once. Doesn't could the first play if bInitiallyOn is true.

[^TOP]
WayBeacon

OK, these don't seem to be used much as far as I can tell. If anyone knows then please let me know.

There are references in 2 functions in PlayerPawn.uc and also in Bots.uc

I think they are used for debugging, to check where bots are heading (it is spawned as a little unreal lamp).

[^TOP]


Unreal Editor Maximum [unrealism.com/unrealedmax] -SPECIAL EVENTS

SPECIAL EVENTS

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

WHAT'S UP WITH THIS?

There are a 101 things that you can use special events. They allow you to do some fantastic stuff. If you were to place a special event (located under Triggers for those who didn't know) in your level and go to its advanced properties and check out Object|Initial State it would give you a list of what you can do with the special events. This tutorial aims to explain all but two of these. The special event almost always gets triggered by a trigger - I have never come across another way - this doesn't count FortStandards used in assault. The way to do this would be to set the event of the trigger and the tag of the special event to the same. Ok, Lets get on with it.

SPECIAL EVENT INITIAL STATE LIST:

  • PLAYER PATH:

Not much to say about this other than read my interpolation tutorial. It is used only in conjunction with interpolation points. It is used to create opening / ending sequences but that's another tutorial altogether. Anyway probably less than .5% of people will want to create those sequences - if at all such a large number exists.

  • PLAYERS PLAY SOUND EFFECT\ PLAY SOUND EFFECT:

The next two under initial state may look the same ....... or they could be different. Yes, they are different but in a very subtle way which is why I'm explaining them under one place. The difference is that Players Play Sound Effect "affects" all the players in the map. This means that no matter where the player is on the map he will here the sound. It will continue to play even if the instigator dies or there is no one in the vicinity of the special event. It will continue to play for the remainder of the time until the time or frag limit is used/reached. I prefer to use these only in assault maps at the very end and use stuff like sirens as the sound. On the other hand Play Sound Effect will play and be heard only in the vicinity of the special event (naturally this will be affected by the sound radius).

HOW TO SET THESE UP: Ok now that you know the difference setting it up should be a snap. The event of the trigger and the tag of the special event should be the same. Under Object|Initial State choose what suits your need. Expand special event and set bBroadcast to true so that players hear the sound. Still under special event set the sound to what you want. If you chose play sound effect you may want to change the values under sound - radius, pitch, etc. You may also want to change sound volume if you used Players Play Sound Effect - obviously here the radius does not matter since players will hear it anyway.

  • KILL INSTIGATOR:

It does just what the name says it kills the person who triggered this event immediately without a time delay. You use this in special situations (haha that's what this tutorial is about) not covered by zone markers like - lava, slime, nitrogen, etc. For example if you set up a lava bed and make it into a lava zone if the player were to jump into it because of the lava zone he would be killed instantly. Use this instigator in situations not covered by the available zones - like space.

  • DAMAGE INSTIGATOR:

Unlike the kill instigator initstate the damage instigator kills the player slowly - like water - the difference being that the player can escape damage by stepping out of the radius of the trigger or getting killed altogether. Set it up as you would normally. Under special event|damage give the amount of damage per second that you want to be caused to the player. If you want the player to be killed slowly you can use 10 which is a nice value and some very high number to kill him off instantly. Under damage type you can use the standard types of damage by entering fell, corroded, burned, etc. bPlayerViewROT if set to true means that the player can rotate and look around while being dealt damage - say while falling from a cliff.

  • DISPLAY MESSAGE:

On being triggered it causes only a message to be displayed on the screen. If you want all the players including you to see it don't forget to set bBroadcast to true under special event and give the message that you want to be displayed on the screen in the message box.

GENERAL SPECIAL EVENTS NOTES:

Don't confine yourself to one initstate. For example you can have a trigger set off the special event with its initstate at player play sound effect, give a message under special event and and a damage amount, set bBroadcast to true that way you shove three steps into one.

The more mundane uses of the special events are usually done in Assault. You can have a message displayed on the screen after a certain point. What I mean to say is that if you have a huge level and if you want everyone to be aware that the attackers have crossed a certain point yet not make it into an objective then special events is what you need.

One thing people forget on making "kill instigator events" for things like falling off a cliff and what not, is to set the proper collision radius of the trigger. I cant give you an exact number as it depends on your level but usually its a value above 1000 or something nice and big. I usually use something like 20000 for cliffs - but the number for your level can only be arrived at by experimentation. Another nice use of special events is to use it for quake 3 arena style jump pads - you can use the play sound effect whenever someone takes a jump. I think you've had enough of my rambling................... for now.


Unreal Editor Maximum [unrealism.com/unrealedmax] -MISCELLANEOUS KEYPOINTS

MISCELLANEOUS KEYPOINTS

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This is the second installment in my miscellaneous series, aiming to explain all the various actors found under key point, in the classes menu. You can use these actors to make custom boats, fighters, etc. move around in a realistic way (the main object of the tutorial); trigger off sounds, etc.

NOTE: @#! - It would be nice to use that actor in every level that you make.

I. PATH POINT & OBJECT PATH - THE BEST THING THAT HAPPENED TO CUSTOM MOVING BOATS, FIGHTERS, CARS , ETC.

Caught your attention didn't I?. Its true pathpoints are the best thing that happened to stuff like boats and fighters. They work just like interpolation points, the difference being that where Interpol's direct the path of the player, pathpoints direct the path of movers. If you have read my interpolation point tutorial you'll understand that this is just great for those boats. If you were to make a boat using just a mover its movement would be dictated by the numkeys and it would look really odd - the movements would seem artificial. This is where pathpoints come in - they direct the path of the boat making it seem natural. I'll give an example to better explain this concept. Falcon One strap yourself in we're going on a flight, lets jump to it:
1. Lets create a room for the fighter to do the bombing raid in - say about 768 x1024x10000.
2. Make your fighter and add it in as a mover at one end of the box. You may want to make this into a dynamic light mover by going to the movers properties and under mover changing bDynamicLightMover to true, don't forget to set the values under lighting after you do this. Under movement you may also want to set the rotation like yaw and pitch. Give the mover a tag and set object initial state to NONE. You may also want to set the move ambient sound.
3. PATH POINTS: This mover will move according to the path points that you place in your level. If you wanted a fighter to just come in straight and go out you could just set the key frames. But if you have a huge winding canyon and want the fighter to weave in and out - you should use path points, COOOl!
TIP: There cannot be more than 35 path nodes in a level. The first and last path points are dummies, which means that if you wanted the fighter to move through 10 points you would need to add in 12, the one at he beginning and the end being dummies. A level must have a minimum of 4 path points.

Add in the amount of path points that you want the fighter to move through in your level. Say you want your fighter to move left to right, right to left and just weave crazily all over the place just place in path points at all the "points(?)" that you want the mover to turn at. If you want the mover to come in low and then move off higher just place path points that form a V. Place the first path point behind the fighter which is outside the level (remember you cant see it in the 3D view) and the second point in front of it where ever you want the fighter to start off.

PATH POINT SETTINGS: Open up the path points properties and expand path point, here you'll find three values:
- curvespeed: Determines the direction of the fighter mover at that point. Play around with this value for the best one. You may want to change it for each point depending on the situation.
- sequence_number: The first point will be 0, the second 1 and so on in a linear line.
- speedU: Determines the speed of the fighter at that point. If you want the fighter to come in fast and slow down and then take off fast this is the value that you should configure. A value of .25 will move the mover through that point in 25 seconds.
Also under movement you should set the rotation values that you want the fighter to take at each point.

Remember the last and first path points need not have curve speeds and speedu's set but must have the sequence number put in. The curve speed of the second point (sequence number of 1) will determine the initial direction of motion and the last but one point the end direction. The fighter will be placed on the second point on entering the level, because as stated above the first point is a dummy.
4. OBJECT PATH: After you have the path points set out, locate and place in an object path actor (cant locate it? damnit this is a key point tutorial find it under key point, still don't see it? visit a doc maybe he can help :). Open up its properties and expand object path, here are the three groups of settings that you will find:
bAlterPitch, bAlterRoll, bYaw - You could set these values to true if you want the mover to change its yaw, roll, etc. This will be affected by the values of the rotation that you gave under mover.
RAdjust - If you set any of the above to true, give the amount of yaw or what ever that you want be it to be adjusted to here.
PathActorTag - The tag (under events) of the fighter that I told you to set before.

Now expand advanced and set bStatic to false (if I may be so bold as to point out a slight mistake here - I mean object path is used to set the mover to move then why on earth is bStatic set to true by default).

Place a trigger nearby and give it an event, set the same as the tag of the object path and ALL the path points. Whoohoo!!! Sierra Hotel Falcon One, that falcon topic is now a smoke and hole in the ground. Now on playing the level you should see the fighter come in and go out of the level.

GENERAL NOTES

  • MY SETTINGS: Mover Rotation- -16874; All Path Points- rotation 50, curve speed -300, speedU - .30 for all but two which was set to .10, sequence numbers were set normally; Object Path- bAlterYaw true (rest false), RAdjust only yaw set to 18000.

  • BOAT SETTINGS: While making a boat that you want to see doing all sorts of twists and turns first add in the mover and then the water. SpeedU is the key to making the boat seem to start of slowly and then take of. Depending on the size of the river set the rotation for path point, the reason I'm mentioning this is that don't give it some humongous value, something like 50 or so should be nice enough.

  • To put your Falcon (if anyone's wondering, yes I'm a Falcon4 fan) through a bombing raid the best way to do it would be to use a dispatcher. Have the trigger set off the dispatcher along with the other stuff discussed above. Give suitable outdelays for the dispatcher and under outevents set a thing factory's tag (have the thing factory connected to a spawn point - under navigation point - by the same tag); a exploding wall (both the mover and the effect); explosion chains etc. all going off. This requires careful timing, but if you set it up straight the fighter should come in and then it will spawn a war shell, then the wall will bust and then there will be a row of explosions and the fighter will fly out.

  • That's all you have to work under these limitations. What the hell, you didn't expect something like those cool cars we've seen from pre-release movies in HALO, now did you?.

@#! II. AMBIENT SOUND

This just produces sounds again and again. Use this in as many places as you can in your level - the level of reality that it adds is worth it. It is just like setting the ambient sound of any actor. Just go to the sounds properties, expand sound choose the sound that you want to use in the SoundFx browser and hit use. Play around with the pitch, volume and radius settings. For example if you have a fan in your level it would look mighty funny if it did not produce any sound at all. You could place some ambient sounds in and around (this is where it proves more helpful than setting the ambient sound of the fan actor) and use the fan sounds. The radius is also very important. I find that very few mappers (except the pros of course) even bother with ambient sound, but it adds greatly to the "ambience" of a level so you should use it a lot.

TIP: After the placement of all your ambient sound actors and setting their radius etc. hit the joystick button (so that it is unselected) in the 3dview and fly around to see how the sounds would "sound in the level". This should give you an idea of which sounds need their volume and radius adjusted.

TRIGGERED AMBIENT SOUND

Do I even need to say it. Just triggers of the sound and makes it play on and on. What is the point of it?. Say you have to destroy a machine as one of you assault objectives. You could have a normal sound for the machine, on the machine being destroyed you can have the triggered ambient sound set off so that it emits a broken hiss (for such an effect make sure binitiallyOn is false and bPlayOnceOnly is again false). Nice effect!.

@#! III. BLOCK ALL

Another nice actor. Just as the name suggests it blocks anything from passing it. This is affected by the collision radius and height under collision in its advanced properties. If you were to place a decoration like a lamp in your level make sure that you add in a block all in its center. The application is so wide I cant explain everything here.

TIP: To set the collision radius properly so that it has the proper reach to it, select the block all, set its radius, go to the overhead view and in the actor menu choose radii view. You should see a red circle around the block all, showing the area that the block all will block.
HINT: Even though we don't need it anymore, block monster blocks all actors found under the pawn menu and lets you pass through, with the block player doing just the opposite.

IV. DYNAMIC AMBIENT SOUND

This actor plays sounds based on the probability factor listed by you.
- bDontRepeat - Two sound should never play in a row.
binitialllyOn - Whether you want the sound to be playing already. Meaning when you approach the actor should you hear the sound or should it start emitting after some time.
- minRecheckTime - The minimum amount of time that a sound will be played before it can be restarted.
- maxRecheckTime - maximum time the sound will be allowed to play before the next is stared off.
playProbability - Higher the number, higher the chance that the sound will play.
Sounds - Choose the sounds that you want to be played (if you want to hear it in a specified way then use the sound that you want to hear first then the next one and so on).

For example I used - bDontrepeat - true, bInitiallyOn - True, maxRecheck -5, min Recheck - 1, playprobability - 60, and bats, crickets and swamps for the sound.
HINT: Unlike ambient sound you cant hear the dynamic ambient sound in the 3d view by turning on real-time (the joystick).

V. a. EARTHQUAKE

Just creates an earthquake. If bThrowPlayer is set to true the player is thrown around (oh really? I didn't know that! :), duration - how long the earthquake should last. Magnitude - the size or the effect of the earthquake, radius - the area affected - both these values have to be arrived at by a process of experimentation. Have the earthquake set off by a normal trigger through tags and events. Remember, this actor only shakes the player.

V. b. CH_EARTHQUAKE

Same values as the earthquake will be present in the properties sheet. A new value called CH_Earthquake will be added - if you set this to true it will throw decorations around. Nice to have this in a room full of decorations, and on entering it have the decorations and the player thrown around instead of only the player.

V. c. THROW STUFF

Just like the above, does nothing else.

VI. LOCATIONID

A locationid works just like the location string of a zone info. The only difference being that the radius of the zone name can be defined and you need not place zone barriers. Great for use in huge outdoor levels. Just place one into your level and in its properties got to locationid and you'll see entries for location name and radius. Say you have a great out door level and you want to call it outside, if you have a waterfall in the level, you can have a locationid name the place as waterfall.

VII. SPECTATOR CAM AND QUAKE CAM

Used only in assault end sequences. For complete information read my assault tutorial on this site.

VIII. THING\CREATURE FACTORY

I'm too lazy to explain this since it has already been explained on this site (now you know why I left myself a loophole by calling this miscellaneous). Have a trigger set off the thing factory. Have a spawn point with the same tag as the thing factory [its located under navigation point and lets the game know that the thing (could be some thing like a war shell from projectiles) has to placed or spawned in that place - you can adjust the way in which it gets spawned by rotating it in the overhead/ side views].

That's it for this tutorial. If you still want more information on the other key points or on these key points please email me.


BB Drac - Unreal Tournament UED2 guide Destroyable walls/windows

Destructable Walls / Windows

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Destroyable walls is in reality not destroyable at all.
What you do is that you trigger a specific actor, ExplodingWall,
which erupt in bits and pieces of glass/wood or walls.

What you actually do when you create most exploding windows and walls
is that you use a mover that is triggered by damage and then
move the mover out of sight of the player.
The mover then trigger the "ExplodingWall" actor.

This is some of the properties you can adjust:

Property | Specific
+Effects |
bOnlytriggerable | If the actor is to be triggered by other trigger or by damage.
+ExplodingWall |
BreakingSound | The sound effect to be played when triggered.
bTranslucentGlass | If glass pieces should be transparent.
bUnlitGlass | Glass pieces affected by light.
ExplDimension | Explosion area.
ExplosionSize | Explosion area.
GlassParticleSize | Size of the pieces.
GlassTexture | Texture used on glass pieces.
Health | Do not seem to be used, expl wall need to be triggered.
NumGlassChunks | Amount of glass pieces to be created.
NumWallChunks | Amount of wall pieces to be created.
NumWoodChunks | Amount of wood pieces to be created.
WallParticleSize | Size of the pieces.
WallTexture | Texture used on wall pieces.
WoodParticleSize | Size of the pieces.
WoodTexture | Texture used on wood pieces.

Collision:
The "ExplodingWall" and "BreakingGlass" actor will block
bullets.
Make sure it do not block weapon fire by setting "+Collision",
"bCollideActor" and "bProjTarget" false.

 Creating breakable windows/walls:
First create two rooms 256x256x256 with a 16 unit wide gap.
Then create a small brush 128x128x16 and subtract it between
the two rooms creating a small opening.

Texture and light it as you wish.

Screenshot

Now we will start to create the mover.
Create a sheet sized 128x128 and AX_Xaxis.

Place this sheet in the middle of one of the rooms, in mid air.
Select any glass texture you want (some good ones in GenIn.utx),
and press "Add special brush". Select Regular Brush, check for
Transparent and press Ok.

Create another idetical brush 16 units apart from the first one.

Now create a brush 127x127x15 and place it exactly in between
both window sheets.
Press "Add special brush", select invisible collision hull and
then Ok.

You should now have a "chunk" of window in mid air.

Screenshot

Now create a brush 200x200x32 and make it surround both sheets and the
collision hull.
Press the "Intersect" button and you should have a nice brush.

Move this brush in the opening of the two rooms and add it as a mover.

When done delete the three objects we created in the middle of the room.

Screenshot

Now select the keyframe 1 for the mover and move it outside of the level where
no-one will be able to see it. Select keyframe 0 again and it will be back
inside the opening.

Now open the properties window for the mover and expand "Object".
For "InitalState" you select "TriggerControl".
Then expand "Mover".
For "MoveTime" you set 0, "bTriggerOnceOnly" and "bDamageTrigger" to True
and "DamageThreshold" to 10.

This mover will now only be triggered if an amount of damage is inflicted equal
or greater than 10.

But no shards will come from this.

Expand "Events" and type "broken" for "Event".

Now open the actor browser, expand "Effects" and "Exploding wall".
Select "Breaking glass" and add it in the middle of the opening/mover.
(If you wanted to create breakable walls you select "Exploding wall" instead).

Screenshot

Open the properties for the "Breakable glass" actor and expand "Events".
For the "Tag" you type "broken".
This connects the actor with the mover.

Expand "Effects" and select True for "bOnlyTriggerable".
Expand "ExplodingWall", select True for "bTranslucentGlass" and
"bUnlitGlass".
Also add the texture you used for the sheets to the property "GlassTexture".

You also need to check all options under "Collision" false or the "Breaking glass"
actor itself will stop bullets, which we do not want.

Now it should be complete.

If you want to try it, add a player start and rebuild.

What we have done is simply a mover that will be triggered when we inflict
10 or more damage to it.
The mover will then trigger the "broken" event when it has completed its
move cycle, which take zero seconds.

In the end the "Breakable glass" actor will create and spread lots of glass
looking effects around, giving the player a firm illusion of destroying a window.

 Destroyable mechanics:
To create mechanics that break is more or less pretty much the same thing.
If you take a look at AS-Frigate you will see that the pressure pump only
change appearance and smoke suddenly show when it is destroyed.

This is how it is done...
Screenshot

(I have moved the mover a few steps to the right. It should be in the middle of
the 'pump').

The players only see one side of the mover which show an intact machine.
When they shoot at the pump the 'fortstandard' will be 'destroyed' and trigger
an event.
This event triggers the mover which only flips side in zero seconds.
The other side of the mover has a texture of a broken machine giving players
the illusion of destroying the pump.

What about the smoke and the sound?

You will also see in this picture a horse/griffin head infront of the pump.
This is a 'SmokeHose' and has a 'SmokeHoseDest' close to the roof of that room.
The SmokeHose is 'InitiallyActive' false and is activated when triggered.

In the left corner you can see a "SpecialEvent" (triggerclass) which is triggered
at the same time as the rest and it contain one ambient sound;
'AmbModern.Looping.steam3'.

Smokehose properties:

Property | Specific
+Smokehose |
Basepuffsize | Size of each 'cloud'.
bInitiallyActive | If the smoke hose should be active from start or when triggered.
SizeVariance | Variance in size of each 'cloud'.
SmokeAccel[] | Increased speed in specific direction.
SmokeDelay | Time between each 'cloud'.
SmokeDelayVariance | Variance in time between each 'cloud'.
SmokeSpeed | Base speed of each 'cloud'.
SpeedVariance | Variance in speed of each 'cloud'.
TotalNumPuffs | Total amount of 'clouds' before smokehose stops.

Explosions:
If you want to create explosions you need to use 'ExplosionChain' actors.
As with 'ExplodingWalls' you need to have 'bOnlyTriggerable' true or false.

Here is the properties you can adjust:

Property | Specific
+ExplosionChain |
Damage | Amount of damage inflicted upon players.
DelayTime | Delay after triggerd and the actual explosion.
MomentumTransfer | Power from the blast.
Size | Size of the explosion.


Exploding Glass

by: Sharky
jneta@ez-net.com

ASSUMPTIONS:

This tutorial assumes you know how to make a mover and set it up with a trigger. If you don"t, I suggest reading the trigger tutorials on unrealed.net.. This is a nice thing to have in DM games for fun. I don"t know why some people I"ve talked think its dumb but i think it was one of the funnest parts of DM games in GoldenEye (n64). Another note if this looks like the Exploding wall tutorial.. well... it is :p i just used it as a base cuz im lazy :)

Tutorial:

First make your level... now make your glass you want to have break... make it into a mover.. Now put the mover in your level.. set its KeyFrame1 to someplace outside your level.. Now add a BreakingGlass next to it.. (its under effects)... next set your mover to the folowing properties..

Events:
 Event - B1 (or whatever name you want for the breaking glass event)
Mover:
 bDamageTriggered = TRUE
bTriggerOnlyOnce = FALSE (this should be false by default but ya never know.. side note: if you set this to true the glass will only break once which would be nice for a SP level..)
DamageThreshold = 10.00000 (put whatever you want to stop wepons from breaking it.. this works for stopping the ctrl fire blaster from breaking it but not the alt fire...)
MoverEncrochType = Ignore
MoveTime = 0.000000
StayOpenTime = 30.0000 - 60.0000 (figure out the right time for the glass to stay gone)
Object
 InitState = TriggeredOpenTimed

Set these properties on BreakingGlass..
Advanced
 bNoDelete = TRUE (if you dont set this the shatter effect will only happen the first time you break the glass.. after that the wall will just disappear.. so you wanna set this :)
Collision
 bBlockPlayers = FALSE
bProjTarget = FALSE
Effects
 bOnlyTriggerable = TRUE
Events
 Tag - B1 (should be the same as Event on the mover)
ExplodingWall
 bTranslucentGlass = TRUE
bUnlitGlass = TRUE

You should now be all set.. rebuild and test out your level..Have fun.. and read the Exploding Wall tutorial for the standard dont make particle size to large.. :)


Exploding Walls

by: Sharky
jneta@ez-net.com

ASSUMPTIONS:

This tutorial assumes you know how to make a mover and set it up with a trigger. If you don"t, I suggest reading the trigger tutorials on unrealed.net

TUTORIAL:

First make your level... now make your wall you want to have explode... make it into a mover.. Now put the mover in your level.. set its KeyFrame1 to someplace outside your level.. Now add an ExplodingWall next to it.. (its under effects)... next set your mover to the folowing properties..

Events
 Event - B1 (or whatever you name your ExplodingWall)
Mover
 bDamageTriggered = TRUE
bTriggerOnceOnly = TRUE
bDamageThreshold = 20.0000 (make it higher if you dont want the alt fire blaster to break it...)
MoverEncroachType = ME_IgnoreWhenEncroach
MoveTime = 0.0000
Object
 InitState = TriggerOpenTimed

Now change the folowing properties on the Exploding Wall

Events
 Tag - B1 (same as Event on the mover..)
ExplodingWall
 GlassParticleSize - Play around with the size until you get what you want for the effect....
WallTexture - Set it to your walls texture...

You should now be all set.. rebuild and test out your level..Have fun.. word of advice tho.. try not to make the particles to big or they will look dumb also play around with the number of Wall Pieces... but again try to keep it low as it will slow down that part of your level if you have like 200 pieces :)


Slippery Surfaces

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

This is something that is quite cool in a level, and most people want to have some part of their level slippery. It might be as simple as having a polished floor that is supposed to be slippery, or perhaps a wet bridge or whatever. Well to do it, really is quite easy, but DAMN hard to find, if you have not done it before. Here is the way to do it.

I assume that you have already got your level made here, and simply want to add in a little area that is slippery.

The perspective of the room that we will make slippery. You can"t see it, but the floor is actually a polished mirrored surface. Now to make life a little easier for me to explain, I have also included a top down shot of the room.

Ok, what we are going to be playing here with is actually a zone. We will need to create a zone that will completely cover the area that you want to have slippery. This in my case will be made with a box (as the room happens to be roughly a box). Here is a pic of the inseide of the room. I have made a cube brush to the same specs as the room, then intersected it just to make sure that it"s exactly the right size.

Now we have to create this into a zone. That"s easy as well. All you have to do is make the following :

That will create the brush that you have just made into a zone portal that is not visible and does not stop the player walking through it in any way. Basically it"s something that only the editor"s will see if they open the map. When you have created your new brush (you should see it as a green brush in the level) you will have to place a zone-info into it. This is where we will actually set the level of slipperiness in it. Open the "Classes" Browser window (where the textures normally are) and select Info-->Zoneinfo You will most likely fin that as soon as you open the Zoneifno bit, you will automatically select "Waterzone" but highlight "Zoneinfo"again, and then place it inside your room. (I find this the easiest in the 3D view). Now you should see the lovely little zoneinfo in your room.

Open the advanced properties of the zoneinfo, and select Zoneinfo-->ZoneGroundFriction. This will automatically be set to 4.000000. This is what we want to change. This particular setting will change the friction that the player has between the floor and the mesh. Keep in mind here that it"s a ZONE setting. That means that if you want only a bridge set to be slippery, you should only make the brush (the one that will end up being your zone) only as big as you want the area to be slippery. If you want a whole area to be slick, then sure make a nice big zonearea, but otherwise be careful what you include as most people will not want everything slippery. The other thing to note, is that everything will be made slippery. I mean, if you have a an area of sand there, it will also be effected, and that would be kinda wierd. I mean I don"t care where you are - Sand is NOT slippery. Feel free to tell me where you will find sand that makes you fall, but I doubt it. Sorry, too much blabbering there. Let me go on.

I want this room to be quite slippery, so I have set the friction level to 1.00000. This should be more then enough to make a player go "Yikes! WTF?!?". Then it"s a simple matter of rebuilding the level, and playtesting it. I have included a final image of the settings taht I have used here, just in case there is a problem in what I have said here, but I think it"s actually quite simple to do.

Well, that should be it. You should now have a lovely slippery area in your map, that will make the best of players slip up, and be extra careful =)

Final Notes : When you add in the zone portal (The special brush) You will see that it seems to actually be visible in the level. That is completely normal. When you rebuild the lighting, you will see that it is not affected, and does not show up as visible anywhere apart from the editor. This is still there as a texture so that you can actually see it in the 3D window, and to make your editing life easier.


Smashing Windows

A room that fills with water

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : WaterTank.UNR

Due to the nature of the Unreal engine, this is not really possible to do but if you’re careful you can simulate it and persuade the player that this is actually happening. This may or may not be useful, but it will give you a technique that you may be able to adapt for your level. To go into every exact detail on how to create this would take me ages, so I'm going to assume you're familiar with most editing techniques. If you're in any doubt, open up the sample file in the editor and you'll see more clearly how I achieved this effect. There are disadvantages to this method, but if used cautiously it could work quite well.
Tutorials you will need to have read are: Movers, Zones

1) Subtract a large cube from your world say 2048 x 2048 x 2048 and light it as you see fit.

2) Now create a room based on a hollow cube. The room itself needs essentially to be an added brush. Add what ever details you need but don’t bother with any actors or semi-solids. Make it around 512 x 512 x 512.

3) Once you’re happy with your room, rebuild, save and intersect the whole room and add it near the top of your first subtracted cube as a mover. You can delete what you used to create your mover with now and rebuild.

4) Now build a sheet and create a water zone sheet so that it overlaps the width and bread of your subtracted cube (say 2060 x 2060). Add it so that it just overlaps the floor of your moving room. Add a waterzone info actor to in the subtracted cube but below the water sheet.

5) Set the mover to “trigger toggle”, set the move time to something like 15 seconds and make keyframe 1 so that the room is completely underneath the water sheet. You could also give the looping ambient sound for the room a waterfall noise to add effect.

6) Add a light so that it lies centrally within the room and then add a player start just above the floor.

7) Now add a trigger somewhere in the center of your moving room but close to the floor, set it to trigger once only and set its event field to the same as the tag field for your moving room.

8) Now test the level and walk to the center of the room. You should see the water level rising and you with it. Obviously it’s the whole room that’s moving, but the illusion is that you have a room that’s filling with water.

9) Getting in and out of a room like this can cause complications when trying to keep up the illusion. I got around this by using a hole in the floor of the moving room and adding an extra mover to fill in the gap as a false floor. Both the fake floor and the room would move down simultaneously in the same time, but the fake floor had an extra keyframe which dropped down further once the room had stopped. You entered the room via a teleport. You may find another approach to do this, this is just one method.


Smashing Windows

Water SkyBoxes

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : WaterSky.UNR

If you’ve ever wanted to create the feeling that you’re in a base submerged deep in the ocean with fish swimming in the distance and giant squids floating around, here’s how you do it.
Tutorials you will need to have read are: Zones, Skyboxes

1) Create a very basic room and set the walls as a fake backdrop so that you can view your ocean when its finished. Light it, add a player start and make it a single player gameinfo for the purpose of this tutorial.

2) Now, subtract a large cube say 2048 x 2048 x 2048 with some watery textures with the “wavy” effect on. Add a waterzone info actor (make sure the info actor is not at the center of your cube). Rebuild.

3) Now create a smaller cube brush about 128 x 128 x 128 and make sure its positioned right in the center of the first cube. Instead of adding or subtracting this as a brush, choose the “Add special” brush as you would for placing a sheet in your level. Now select the “zone portal” option and hit “OK". Rebuild.

4) Lets just check that you now have a zone within a zone. In the 3D view window, select the view option and choose zone/portal view. You should be able to see the two cubes as different colored brushes. If you do (and you should) then we can move on to the next step.

5) Inside the smaller zone cube add a skyzoneinfo actor and rebuild.

6) Add some water creatures to the outer zone and add some lighting too. Rebuild and test the level, you should be looking out into a vast ocean.


Smashing Windows

Warp Tunnel

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : Warp.UNR

Tutorials you will need to have read are: Teleporters and Zones

This effect creates the impression that a player is sucked along a tunnel of light into a new area.

1) Create a cylinder brush about 2048 high with a radius of 128 and no less than 16 sides. Select a texture that looks like random power fluctuations or a similar effect (XFX.UTX has some good ones). You can also add in random, transparent sheets in the tube along its length with another weird effects texture just to add to the feel of it. You could add a light in the cylinder, but making the textures “unlit” will probably look good.

2) Now subtract the brush and make the textures unlit. You also need to align them so that the tunnel looks seamless. In the overhead 2D window make sure the cylinder is positioned length ways (stretching from left to right).

3) Now introduce a “zoneinfo” actor. In its “zoneinfo” properties set bgravityzone to “true” and then open out the gravity fields that have x, y and z. You’ll notice that z already contains the value of .95 which simulates normal gravity. Change z to 0, and change x to -2000 (depending on which way around you have your tunnel, you may have to experiment or check out the sample map). This will cause the player to be dragged in that direction. If you wanted the player to be dragged in the opposite direction change it to 2000. Also set your zone terminal velocity to 2000 (this tells the engine at what speed to stop accelerating). Now rebuild and save so that the zone takes effect.

4) Add two teleports, one at each end of the cylinder. Give the one on the left a tag called “warpin”. Now select the one on the right, and write “warpout” in its URL field. In the 2D overhead view window, select actor menu option and pick “radii view”. You need to make sure that both teleporters collision radius covers the height and width of the ends of tunnel. You can adjust the radius in the collision property of the teleporters. They’ll probably need to be set at 128 radius like the cylinder itself.

5) Now create a small room for your player to start in and create something that you think could look like a teleport pad. Place a teleporter on there and call it “warpout” in its tag field and “warpin” in its URL field.

6) Now, when you’ve rebuilt and saved, you can try it out. The player should be able to step on the pad, and they will enter the tunnel which will drag them to the end and back in the original room. Notice that the player will appear facing in the same direction in the tunnel as they were when they ran onto the teleporter in the start room. It’s a good idea to remember that so that your player doesn’t end up flying backwards!


Smashing Windows

Pawn Scripting

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : Pawnscript.UNR

This tutorial is mainly for people trying to create a single player map and will demonstrate how you can trigger a Nali to run along a predefined path and use a spell to open a secret door. This sort of thing is not only useful for making interesting scripted events but also useful for creating cut scenes in your maps.
This example can be used by most other pawns too. For example, you may want a Titan to walk along several steps and then beat his chest. The principle is the same.
Tutorials you will need to have read are: Movers, Monsters AI which you can find at the Unreal Technology page.

1) First create a large size room (1024 x 1024 x 1024 will be fine) and then cut a smaller area away from it to create a secret area that the player can walk in to. Create a mover that acts as a door covering the opening. Make the door the same texture as the wall so that it won’t be easy to spot it. Give it a tag called “open” and set it up however you want to move the door.
Its probably a good idea to give your mover a delay of about 2 seconds (under mover/delayTime) to give the Nali time to do his stuff.

2) Now add a Nali into the room and place him a good way away from the secret area.

3) Position your 3d view camera as if you are looking through the Nali’s eyes. Now, amongst the navigation actors in the actor browser choose “alarm point” and using the 3d view, add the alarm point on the ground a few paces in front of him. Once you’ve added that, move your 3d view toward the alarm point until you’re on top of it (just as if the Nali had walked up to it). Now add another alarm point a few paces ahead again. Repeat this process until you have a chain of alarm points leading up to the secret door. They don't have to be too close together, but close enough that the Nali will be able to see the next one he needs to get to.

4) Now you need to set up some details in your alarm points. Click on the first one and give it a tag called “n1”. Now open up the Alarmpoint property and you’ll see a field called “Nextalarm”, label this one “n2”. Set the bwait field to “true” on all the alarm points (that will cause the Nali to beckon you closer if you aren’t near him). Set the nofail field to “true” on all your alarm points too (this stops the Nali from getting easily distracted).

5) Your second alarm point should be given the tag “n2” and the nextalarm field should be called “n3”. Hopefully you’re starting to see now that each alarm point points to the tag of the following alarm point. When the Nali reaches the alarm point he will target the next one and wait for you to follow him.

6) The final alarm point must be set up slightly differently. For this one you need to tell the Nali to perform an animation sequence so that he looks like he’s casting a spell. There is a field in the alarmpoint properties called “playanim”. For this tutorial type in “spell” in that field.

Digression: Each scripted pawn can perform a number of different animations. To find out what these are choose “Mesh viewer” and then from the list choose the actor of your choice. In the anims lit you will see all the different actions that your pawn can do. Make a note of the anim you want your pawn to use and that can be placed in the “playanim” field.

7) It isn’t enough just to put the anim name in that field. The Nali also needs to be given enough time to do the anim when he reaches the alarm point. In the pause field type in “3”. That should be enough seconds to get him to perform his animation.

8) Next you need the door to open at the moment that the Nali begins performing his animation. To do that, simply place the tag of your mover (in this case we called it “open”) into the event field of your alarm point. As soon as the Nali arrives at the alarm point it will trigger your mover.

9) Lastly we need to set up the properties of our Nali and trigger him. Open up the Orders section of the Nali properties. In the Alarmtag field type in the tag of your first alarm tag (which in this case is “n1”). You’ll probably find that when he sees you he will trigger anyway. But to be on the safe side, put a trigger in the path of your player with its event field set to whatever the Nali’s tag is.

And that's all there is to it ....

TIP: Alarm points act as pathnodes and as such its always a good idea to do a "paths build" when you've got them where you want them. Also, try not delete any of them if you can. Even if you make sure that you match up the events and tags afterward, it still can cause problems. If you do run into problems, its best just to delete your alarm points, do a path build and add some new ones in.


Smashing Windows

Multi SkyBoxes

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : MultiSkies.UNR

Tutorials you will need to have read are: Skyboxes, Movers (hmm, that gives the game away!)
If you’ve looked into some of the levels that came with the original Unreal, you’ll probably notice that some of them actually have two skyboxes. This gives the mistaken impression that you will actually see two different skies during the course of the level which isn’t the case. The skyboxes you see in the editor are created so that one will work on PC’s set up for high graphic performance and the other for low graphic performance.

It is possible to have more that one type of sky in Unreal/UT, but as with so many other special effects you’ll have to do it through illusion! It involves creating a basic skybox area in which there are lights toggled on and off and two sets of moving brushes that switch between each other, rather like a theatre switching scenery when the curtains are down!

1) Create a basic room with all your walls and ceiling set up as “fakebackdrop” as you would normally. Put a player start in there, light it and set the game info to singleplayer.

2) Now create a skybox in the usual way but use trigger lights instead of ordinary lights. Get it looking exactly how you'd like it and then delete the skyzone info actor (if you'd put one in there).

3) Now create a second skybox completely different to the first and again using trigger lights rather than ordinary lights. Do the same as last time and delete the skyzone info actor.

4) Neither of these will be your real skybox, instead they will be the blueprints for two movers that will act as the brushes for your skies. For your real skybox, create a large cube which is much bigger than either of your first two skyboxes.

5) Make your builder brush slightly larger than the first skybox you created and intersect the whole thing. Now position the brush inside the large cube you created in step 4 and create a “mover” brush with it. Do the same for the other skybox too and ensure that both movers have their central point are in roughly the same position.

8) Take your first “skymover” and call it "sky1" in its tag field. Also make sure bdynamiclightmover is set to true. It should also be set to trigger toggle and have a move time of 0.

9) Move it outside the cube (the start position). Now select keyframe 1 and position it back where it was a moment ago inside the large cube in your “real” skybox area (end position). Now reset it to keyframe 0.

10) Repeat steps 8 and 9 for the second "skymover" but call this one "sky2" in its tag field.

11) Now place a skyzoneinfo actor in the large cube. You'll probably need to place both "skymovers" to position 1 temporarily to make sure you put the skyzoneinfo actor in the right place.

12) Now for the lights - here's where you find out why you had to use trigger lights ....
Select all the triggerlights inside the first of your original sky boxes and drag them to the corresponding position inside the large cube. Set them to "trigger toggle" in their initial state, give them all a tag name of "lights1" and set the "initially on" field to false. It will also be helpful for you later if you give them a group name of "lights1" too in case you want to change them all later.

13) Do exactly the same thing with the trigger lights from the second skybox you made in step 3 but give these a tag name of "lights2" and also the group name of "lights2". You should now have two sets of lights within your new skybox ready to switch on and off at your leisure! (Remember to set your skymovers back to keyframe 0)

14) All that's left for you to do now is trigger them off. Make sure at least one of these skyboxes is triggered at the start of your level. You can use an ordinary trigger to set off a dispatcher that triggers "lights1" and "sky1". When you want the player to see a new sky, simply trigger "lights2" and "sky2" in the same way. Remember though that if you trigger one of them on, you must trigger the previous one off if it was showing up.

Of course, there is one disadvantage with this method. Only one of the skyboxes can be viewed at any one time so you'll have to be selective how you use this.


Smashing Windows

Locks and Keys

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : Locknkey.UNR

For this you could actually use script to make a real key and keytrigger. You can get this from Chimeric. But if you don’t want to bother with that there is a way you can do this with careful usage of triggers and movers.
Tutorials you will need to have read are: Movers, Triggers

1) Create a sizeable room connected to another room via a passage that is blocked by a mover in the form of a door. (See the tutorial on movers if you’re unsure how to do that). Make sure the door is set to “trigger toggle”. Call it “open” in its tag field.

2) Next, place a trigger in front of the door. Set the event field to “open” so that when the player walks into the trigger it opens the door.

3) In the trigger’s “object” property set the “initial state” field to “Other trigger turns on”. In its “Trigger” property set the “initially on” field to False. In the trigger’s. Call the trigger “Gotkey” in its “tag” field. Now the trigger will only open the door when it is itself switched on by something else.

4) Now you need to make a key that will unlock the door. Create another mover in the shape of a key and small enough that the player will think they can pick it up. It may also be a good idea to make the textures “unlit” so that the key will stand out like all other items. Set keyframe 1 so that the key is way of the map somewhere and set it to “ignore when encroached”. You also need to set it to “trigger toggle” and the mover time to zero. Call it “key” in its “tag” field. You should also put an inventory pick up sound in the mover’s opening sound field (you’ll find that in the Unrealshare sounds under generic”. With the mover set up in this way, it will appear to disappear and be picked up in the same way any item would once it is triggered.

5) Now place a trigger over the key and set its event field to “key” and make it btriggeronceonly = true. (note: you could set the mover to be bump or stand open timed, but if you do this the key will eventually reappear again). Now when the player walks over the trigger, they will feel as though they picked the key up.

6) Now set the mover’s (your key) event field to “Gotkey”. As soon as the key is moved the trigger that opens the door will now be activated allowing the player access through the door. Additional triggers should also be added to inform the player that they “have the key” or “you need a key for this door”. These can be done by using special event triggers with the same tags as the associated events.


Smashing Windows

Deadly Lasers

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : Lasers.UNR

Tutorials you will need to have read are: Movers

For this we will create a vertical laser beam that can be switched on or off, and when the player walks into it they will get either hurt or killed.

Tutorials you will need to have read are: Movers, Triggers

1) First create a standard room (singleplayer game, a light and a player start) in which to put your player and the laser beam. Making a neat little platform for your laser would look good too.

2) Now create a mover that will act as your laser beam. The textures from XFX.utx can be quite useful. Make the mover from two sheets crossing over each other about 1024 high and 8 wide (it should look like a small cross from your top view, using 4 sheets inn the shape of a star would be even better). They ought to be unlit and transparent.

3) When your mover is made, position it off your map somewhere for its first key frame. Set its ambient noise to something that sounds like electricity (try Ambmodern.uax). Set the mover so it “ignores when encroached” has a mover speed of “0” and is “trigger toggled”. Set mover keyframe 1 so that it is positioned where you want the laser beam to appear in your room (remember it should be vertical and also remember to reset it to keyframe 0). Call it “laser” in its tag field.

4) Now we can add the triggers that do all the work. First add another mover or a trigger that will act as your switch to turn on the laser so that your player can easily see it and use it. Set its event to “laser”.

5) Now add another ordinary trigger right in the spot where your laser will appear. Set its collision radius so that the height and radius match the laser beam mover when it is in keyframe 1. Set its initial state to “other trigger toggles” and in its trigger properties make sure it set to be “initiallyon = false”. Call it “laser” in its tag field and put “frazzle” in its event field.

6) Now we need one more trigger. Place a “specialevent” trigger anywhere in your room, it doesn’t matter where. Call it “frazzle” in its tag field. Set its initial state to “damage instigator” and set the damage amount to whatever you like. In damage type write “burned”.

7) Now what happens when you play the level is this: At first nothing will be visible to the player within the room apart from the button that starts up your laser. The player pushes the button and the laser mover is triggered to appear in the room. The trigger where the laser is positioned, is also switched on. When the player collides with the trigger while it is on, it uses the special event trigger to hurt the player. Pushing the button again will move the laser off the map again and turn off the trigger that hurts the player.


Smashing Windows

Glowing Teleport

by EZkeel

Ezkeel@nikodemus.co.uk

Downloadable files : Telelight.UNR

This tutorial will help you create a pulsating light that changes color (I generally use these for teleports).
What you will be doing here is not to take a light actor and keep changing its color, but to carefully place different colored lights that turn on and off over each other at specified times giving the effect of a changing light source.

Tutorials you will need to have read are: Triggers, Lighting

1) Build a test room with a playerstart, an ordinary light source and set the gameinfo to be a singleplayer game.
Now add a zoneinfo actor into the room, open up its zoneinfo properties and set "bFogZone" to true. The fog zone is so that you will actually see a ball of light.

2) From the actor browser choose “trigger light” from the list of lights (I'm pretty sure either of the two will do).
Add this light to the area where you would like to put your teleporter. Set it up as shown in the picture:
In its “Object” settings set it up as “Trigger toggle” in the initial state field.
In its “Trigger Light” settings make the change time 1.
In its "Light color" properties, set it up so that it has a red glow. Brightness 64, hue 0, and saturation 0.
In the "lighting" properties under the fog settings, give it volume brightness = 150, Volume fog = 64 and Volume radius of 4.
Give it a light type of "subtle pulse"
Give it a tag called “L1”.

3) Now, with the trigger light selected press Ctrl-W to duplicate it. (You'll need to adjust its position ever so slightly so that it is in the same place as the first light). Change the setting in this one’s light color property so that it is yellow instead of red. Hue=42, Saturation=127. Give it a tag called “L2”.

4) Once again, use CTRL-W to duplicate it again, and make this one green by changing the light hue to 80 and the trans to 0. Give this one a tag of “L3” and leave the other settings the same as the previous one.

5) Do the same as step 4 but make this one blue by changing the hue to 170 and the saturation to 127 and giving it a tag of “L4”

6) Now add a dispatcher trigger. Give it a tag of “go”. In the dispatcher property you have events and delays. Set them up so they look the same as in the example on the far left.

8) Now add a Timed Trigger. Set it to be repeating with a delay time of 1 second. Give it a tag of "Timer" and set its event field to "go" as in the picture on the left.

9) Now rebuild your level and save it. You may see a solid ball of white light where your lights are in the 3d view but that depends on your video board setup. The editor is simply showing you all the lights in a static “on” position regardless whether they start as on or off when the level runs.

10) All you need now is a trigger to set them all off. This could be a mover or just an ordinary trigger. For the purpose of this tutorial just add a normal trigger and set its btriggeronceonly property in its trigger section to “true”. Set its event field to “timer”. Now when a player walks over the trigger, it will start the dispatcher and the lights will give you a cool teleport effect.

Note: Obviously these lights don't actually work as a teleport. You'll need to place a teleport in there in the usual way of course.


Ladders

By: Dr. Slue

drslue@gamesden.net.au

Slue

This tutorial covers:

Umm...ladders. I thought i just said that?!

Forward:

This tutorial is about make those ladders that you used to find in all those 'Oldskool' games such as Goldeneye (64) and Doom etc. the ones that just defied the whole reality concept: holding [in many cases a two handed] gun and running straight (upright!) up a ladder. So i thought i could show you guys how to do such a silly thing with UT. Enjoy! Note: there are 10 images on this page so it may take a while to load, just be patient :-)

Content:

Here we go. I assume that you already have your map ready for this, since this is the intermediate/advanced section. The most common types of maps that you will see this in, in UT are probably TO (Tactical Operations) styled maps, and you don't really see a lot of them in any UT gametype (mod or otherwise). Anyway, here is the level that i'm working with:

Nothing fancy, but just something to use for this tutorial. There's a little chimney thing on the roof, so i'm just gonna pretend that, that is what i am using this ladder for. So i am going to build a ladder to get you up there.

To do this, first of all, you need to build yourself a little ladder brush. If you want, you can just build two long side panels and then some rungs, using just the cube brush. However, this will cause it to have a high poly count (more visisble polys on screen causes the game to run faster), so i will show you how to reduce this. So, make your ladder now, but don't bother texturing it yet.

This ladder is made up of 6 different brushes which can really drag things a bit, if you have a lot of detail in your levels (all of these sorts of things combined).

Now, make a cube (or whatever shape fits) around the ladder with the builder brush so that it is fully surrounded, but make sure nothing else is inside the cube. It should look rather like this:

Now press the Intersect button ( [image] ) which will then make the builder brush into the shape of your ladder, but as one brush. Now you can delete your other brushes (in my case, all six of them) and then add this one. There may not be any difference in poly count, it may look like absolutely nothing at all has changed, but even so, you have at least managed to clean up your brushes. 1 is a much more desirable number of brushes than six. It's just a lot cleaner and also much easier to move around if you need to. Anyway, now we can continue. Feel free to texture your ladder now, and then move it into place.

Now that my ladder is sitting in the desired position;

I will now show you how to make it useable in-game. Make a staircase, to the hight of your stairs or the hight of what you are trying to reach (e.g, i only have to make it up to the top rung of mine). Make it from a Linear Staircase Brush (the straight one). Try to make the length of the steps short, so that the Invisible Collision Hull (if you don't know what i'm talking about, don't worry, it'll be explained soon) wont be too big. And remember, that the maximum height step that a player can go up is 32 Units, so try to keep it under that. But the higher for this the better really, because the higher each one is, the less steps are needed which means that the stairs aren't sticking out as far. I kept mine at 28 Units, and only 8 Units long, with 9 steps. It looked like this:

This next part is very important, it is what will make it useable in-game. When your Builder Brush is in place, go to Add Special and then select Invisible Collision Hull from the drop down box.

You will now see a staircase covering your ladder, in the current texture. Don't worry, you wont see this in the game, it's invisible in the game, hence its name. However, depending on how long you made each step, all that is infront of the ladder brush itself, will still stop people walking right next to the ladder itself (coming from the side), it's an invisible barrier. But when approached from the front, it will act just like a normal staircase. To change the overhang/excess invisible wall, you can try making the ladder slanted (which is a lot more realistic anyway) so that there will be some excess at the front and back instead of a whole lot just sitting at the front. Just remember, that you are walking up the stairs when you play it, so don't let the rungs block the player or whatever by slanting it too much.

It's really up to you how you use them and how effectively they work. So just give it a rebuild, and try out your level =D Good Luck.

Level shots:

Success! I got onto the roof!

The invisible barrier in action, i could not walk forward due to the ICH. This is what i mean by the excess, it is necessary to use the stairs, but can be annoying in games.

The whole invisible stairs thing in action!

This concludes todays session, i hope it worked for you and you learnt a lot from this!

About this tute: Well i'd seen many people over time that have asked this question, and so i thought i might as well make a tute on it...and because its been a week since the last tute X=D

Plus, it wasn't just teaching you how to make ladders, but it also taught you how to intersect brushes (well at least one type of intersecting) and how to make/use ICH. If you ever want the level from one of the tutorials to compare to, then dont hesitate to ask. If i still have it, i will either send it to you or put it up on the web if more people ask for it.

About the tutes: I decided to write some tutes because of the fact that heaps of the tutes on the net were written for UnrealEd1 and that really craps up the way things work and more often than not, it ends up very confusing with an unhappy little reader crying in the corner...or so i've heard XD

Feel free to e-mail me with suggestions for tutorials , I'll be happy to make them
if I have enough knowledge on the subject.

My E-mail: drslue@gamesden.net.au


Creating Earthquakes

by: Cralex NS
cns@planetunreal.com

How to make a small EarthQuake in your map

Go launch the UED and open up your map.
Open up the Actor Browser, expand Keypoint and select Earthquake.

Now place your Earthquake where you want it to shake players :)
Open up the properties of the Earthquake actor
expand Events and write the tag `quake`
expand Earthquake

ThrowPlayer = True, if you want the player to be `thrown around`
duration = How long you want the quake to be?
magnnitude = How much you want to throw the player?
radius = Radius of your shakings (If you want the EarthQuake to be everywhere on your map,
set the amount very high)

We need some sound on this Quake to make it real, so open up the Class Browser once more and
expand Triggers and then select SpecialEvent

Place the SpecialEvent somewhere around your Earthquake Actor.

Open the properties for the SpecialEvent now
expand Events and write the tag `quake`

Expand Object and select InitialState>PlaySoundEffect
(if you wanted the Quake everywhere select: PlayersPlaySoundEffect)

Now Expand SpecialEvent>Sound and select the sound you wanna use. (Ambiant Outside is a nice pack :))

Now we have an EarthQuake but no we are not finished yet, we want the EarthQuake to be
started somehow, this can be done one several ways, timedtrigger, trigger, TeamTrigger etc.
Just make the Event>Event of the trigger "quake" :)

tutorial by Cralex NS - cralle@wanadoo.dk


Cyclones

by: DaveA
Dave_Arendash@intuit.com

In this tutorial, you will learn how to implement cyclone effects. We will make a "working" tornado of sorts. It will spin you and lift you and throw you on your butt. By reversing direction, it would suck you down. In water, this would be a whirlpool.

Glossary:

Zone: In Unreal, a closed area defined by a Zone Info object.
Cyclone: also Tornado, Twister, Whirlpool, Vortex

There's a storm brewing...

Zones are amazing things. You can be in them and not even know it. In this case, you will. There are properties of zones, namely the direction and strength of gravity, and a "velocity" which can move you around. You can also play with the ground friction. No friction would have you sliding as on ice.

The main property we will play with is the zone velocity. In any zone, you can have it move you around, like a wind blowing or river sweeping you down. But a zone cannot spin you around (unless you know how to do this, please let me know). However, nobody said you can"t have more that one zone. In this example, I create 4 pillar-like zones, arranged in a 2 x 2 square, all side-by-side. Each zone has one direction, and that direction blows you into an adjacent zone. If we were to number the zones, looking down on them, like this:

1 2
3 4
then we will have zone 1 blow into zone 2, zone 2 blow into zone 4, zone 4 blow into zone 3, and zone 3 blow into zone 1.

So, you create your 4 zones, and in each one, you put a ZoneInfo class. On each one of those, you will set the ZoneVelocity X and Y parameters to point into an adjacent zone. In this example:

1 -> 2 is +X
2 -> 4 is -Y
4 -> 3 is -X
3 -> 1 is +Y
You choose the speeds, but they don"t have to be big. Anywhere from 1 to 10 produces a nice effect. You can go faster, but it might not play too well.

You may want to adjust the ground friction for all 4 zones as well. The default is 4, but if you want more of an effect, reduce it.

The Answer is Blowin" in the Wind

Now, to get a tornado to lift you up, you should also set a Z velocity for all 4 zones. Again, smaller numbers will do. For a whirlpool, use negative Z velocities.

One thing I haven"t done yet is actually lift you off the ground, so now it"s time for that. In the example map, if you walk into the twister, it will move you around, but it will not lift you up. You have to jump, then off you go. You could drop the ground around the twister, so the player will already have their feet off the ground entering the zones, but that"s not really cool. You could put a power-up on a pedastal in the middle of the storm to encourage a jump, kinda cheezy. Setting ground friction to zero will not lift you up, you are adhered to the surface until you jump or something else gets you off the ground. It does make it slipperier, like ice, so the wind blows you around faster. But there are two ways I know of to get you off the ground without jumping or blasting: set the gravity to point up, or make a kicker. In this case, the gravity is more elegant. Play with the gravity vectors in the zones. Normally, they point down (-Z). Set all to zero, or even set the Z value positive (1 will do). Up up and away!

Once you are off the ground, there is no ground friction, so two things happen: 1) you can now use any "air-control" (that magical flying ability), and 2) the twister will tend to toss you out one side. If you want the player in the twister longer, you can make it bigger in the XY plane. You could flare the top, so that the top is wider than the bottom. You can also point the velocity vectors more toward the middle, instead of just to the left, right, up, or down. This will tend to keep the player more toward the center of the twister.

Toto, we are not in Kansas anymore...

You may also want to see how it works with fewer or more zones. The fewest would be three. Six or eight would work, may be overkill

For added effect, you could stack one twister atop another. You can set the lower one to be stronger (as in nature) or weaker, depending on what you want it to play like.

You could also try nesting twister zones. Meaning, you can have a "core" set of, say, these 4, and then surround those with more zones. You could make those outer zones more or less "fast" and more or less "inward pointing". If you want to draw someone in and keep them in, make the outer zone point in more. It will toss them around more keeping them "in the zone" heh heh heh. You could also create an "eye of the storm" by having no zone in the middle. Say, 8 zones surrounding nothing, like a hurricane.

Texas City Twister

Zones are inherently invisible. So, as yet, you can"t see the thing, you just see what it does when you get into it. I will leave it to you to design a convincing atmospheric effect. I suggest using sheets with semi-transparent dirty textures. You can use U-pan texture properties to make it look like the stuff is moving. If you want to get fancy, you can make the sheets from mover brushes, set to rotating around the center of the twister. You can also try the Pillar of Fire from the Exodus story, a swirly cloud, sparks, use your imagination.

You should also pick a nice sound for your effect. Real tornados sound like jet engines or big freight trains roaring by real fast.

If the intent of your twister is to do damage, play with the zoneinfos" pain, destructive, and damage settings to suit your needs.

Tempest in a Teacup

These are screen shots from that map. Notice the top view shows the 4 zones. I placed cones in each zone, which point in the direction of the zone velocity vector (or "wind direction") for that zone. Notice in the side views the green rectangles are the twister zones, so this thing throws you almost to the ceiling. If you play this and walk in between the cones, you"ll start swirling around.

This shot"s 3d view is looking down into the "eye" of the storm. I like to use that texture on zone surfaces, as it shows their alignment. In this case the alignment is not critical, but it does show the "wind" direction in the twister.

This shot shows the actual settings for Zone 1.

This enlargement shows the settings in the Zone 1 properties.


Nuke The Whole Map

by: Matrix
atroche@yahoo.com

This tutorial will show you how to simply make an explosion chain that will basically blow up the whole map killing everybody playing. It is very fun to use especially in multiplayer because everybody wonders what happened. Sounds hard? Its actually very easy and a very fun effect to use but you can only use the effect once a game. Oh well, live with it! I won’t get to detailed because there is no reason to but I will explain the basics. I’m expecting you know how to make a pretty big level or a map from Unreal Tournament itself or maybe even a map you downloaded from the Internet. First get to the actor/classes browser then select Effects then ExplosionChain. Like This:

Now this is the more boring/hard part but once you get it over with its seams like nothing. Go back to your map and add an ExplosionChain anywhere you think would be good for your first explosion (the middle of the map works best). Then right mouse click on the ExplosionChain (it should look like a little explosion) and click on properties. Then click ExplosionChain. Like This:

Now if you want a really strong explosion you should make the damage: 9999999999 and the size: 9999999999. If you want a weak explosion you should make the damage about 100 maybe lower/higher and the size about 10/20 and so on. Now here comes the boring part you have to put a whole bunch of those ExplosionChains around the level to make the whole level explode but its worth it (maybe put one in every big room for example). When you are done with that move on. Here is the part where you actually make something that will trigger the ExplosionChain effect causing all the ExplsionChains you made to explode, killing everybody nearby. I’m going to do this with a barrel for example, but you can actually use anything that’s triggerable. First go to the actor/classes browser again and select Decoration this tome then select Barrel. Like This:

Then go back to your map and add a barrel somewhere (somewhere where it wont accidentally get shot with a gun). Then right mouse click on the barrel and select properties. Then select Decoration and go down to EffectWhenDestroyed either type in Class"UnrealShare.ExplosionChain" in the box or click the “….” Button browse to the ExplosionChain then click use. WOW! That wasn’t so hard now was it? Well have fun with your explosions and if you have any questions on how to do something just email me at atroche@yahoo.com


Custom Sound

Custom Sounds in Unreal

    Nemesis
    nemesis@teamanarchy.com

    What you will need:

    1. A sound editing package. I recommend Syntrillium's CoolEdit 96* (or CoolEdit Pro if you feel like shelling out the bucks.

    2. A "tracker" program*. Trackers allow you to compose music (modules or "mods") by arranging digital samples in the order and pitch you want them (much like laying out notes on a staff). I recommend Fasttracker 2.08*. Most trackers are DOS based (it's a tracker thing) and usually support SoundBlaster, GUS, or SB emulation. An .XM file has been included with this package for you to try the exercise below.

    3. A good ear for music and a bit of patience. Learning to track songs takes time.

    What you will NOT learn:

    This tutorial will NOT teach you how to compose music or how to work a tracker. You'll have to read the docs with the tracker or find an online FAQ*. There are also a good variety of tracking tutorials available online*. Beyond that, most music is taste so use your best judgment on what samples* to use and what kind of song you want.

    This tutorial will also NOT teach you the art of Foley (making sound effects). Foley is based on pure ingenuity and is up to you to come up with (or find) the sound effects you want. Here's a freebie (and an example of Foley): Smacking a head of lettuce with a broom handle sounds surprisingly a lot like a skull being cracked in...

    On to the goods...

    Part I: Music

    Start by making a room to play around in (add a playerstart and lights). First thing you'll need to do is create an unreal .umx music file. You can start by switching your browser (on the right) from Textures to Music. Click the Import button at the bottom and select your music file (created in FastTracker or something similar). Unreal supports .mod (standard mod file), .s3m/.stm (ScreamTracker format), .it (Impulse Tracker), .xm (extended mod format), and .far files.

    Your music file will appear in the list to the right. From here you can play it if you wish to make sure it sounds correct. Just click Save and give your music file a name (such as "Trance.umx"--whatever you want). Now that your file is saved you can go to the Options menu, select Level Properties, go down to the Audio section, choose Song and click 'Use' (make sure the song is selected in the list to the right). That will cause your song to be played for the duration of the level.

    There are other ways to start songs (such as triggers) if you prefer to have a song keyed to and event (you have the option of playing it through only once using triggers). Try out the above with the included .XM file.

    Part II: Sound without compromise

    Sometimes finding the right sound for the job is easier said than done. After listening to every sound effect in Unreal and still not having what you want, you tend to get frustrated. Finally you decide, "Screw it, I'll find a .wav or make my own." Well, if you've ever used Windows recorder than you know it's sadly underpowered and churns out huge .wav files. Similarly, you may find the sound you want on the web but it's about 5 times larger than it should be (you don't want your level to be 3+ MB now do you?).

    The thing to do is either A) record and edit your sound using a righteous sound editing tool (such as CoolEdit*) or B) get a pre-made sound into that same righteous sound editing tool. You'd be suprised how much quality is retained by a sound file if it's recorded at 44K/16bit/Stereo and then downsampled to 11 or 22K/16bit/mono. Use your sound editing package to do this downsampling. Listen for audio quality. You WILL find a nice compromise between quality and size.

    Once you've got your sound effects made and edited, fire up UnrealEd and switch the browser from Textures to SoundFX. Since you can't just create a .uax audio file directly you can do one of two things: 1) Load up Extro.uax and delete the 7 sounds in there, Import your sounds, and save it under a different name (BE CAREFUL not to overwrite Extro.uax!) or 2) Just import your sounds into Extro.uax and leave them packaged in there with the first 7.

    Now you've got exactly what you wanted in a sound, and it's small so it doesn't bloat your level up. You can check out the "Advanced Triggers" tutorial on unrealed.net for details on using triggers to fire off sound effects and music. If you have more questions about sound editing and music tracking you can contact me at nemesis@teamanarchy.com. Please do not bother the webmasters with sound editing/tracking related questions. Happy editing, and happy tracking!

    *Some helpful links to references made above

    Syntrillium Software (creators of CoolEdit) (http://www.syntrillium.com)
    A good collection of Trackers (http://www.maz-sound.com/trackers.html)
    The Zen of Tracking (online resource) (http://falcon.invincible.com/~jerm/newcomers.html)
    Some samples to get you started (http://www.th-zwickau.de/~maz/instruments.html)


Wolf's Tutorial Twelve - Sound and Music

Wolf's Tutorials: Sound and Music

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Introduction:

This is an intermediate to advanced tutorial. If you are new to UnrealED then please see my tutorial page for links to Basic Tutorials to get you started.

Sound and Music

So, you think you're level is just a bit too quiet? Unsettling isn't it. Sound can make or break the atmosphere of a level. This tutorial will show you how to create ambient sounds, triggered sounds and music for your Unreal levels. Lights, sound and music can really create a tangible atmosphere for your level. This tutorial will NOT cover lights so you will have to wait for that tutorial, but You will learn the basics of implementing sound and music.

Getting started

To start with build a room about 256 x 512 x 512. Size doesn't matter nor do the textures. Add a light and a PlayerStart. Now build a hallway coming off the room and make it 512 long. It doesn't matter what direction it runs. Add a light in the hall. Now make an identical hall and attach it to the end of the first hall at 90 degrees so it makes a nice "L" shape. Now add another hall at the end of the second one, again at 90 degrees making another "L" At the end of the last leg add another room the size of the first. Add lights in all the rooms and all the halls. You should have something like this:

Ambient Sounds

Ambient sounds are those "background" noises that play in your levels. It might be the sound of a fan or machine running in the background, or a drip from a leaky pipe, or the wind howling in an outdoor area. Ambient sounds can really set the tone for your level. Imagine your player is in a huge engine room and there is no sound. Hmm...seems boring and unrealistic. Now add an ambient sound of an engine hum and BAM! The room becomes real! You feel like you are there. You need two things to make an ambient sound in your level. The ambient sound actor and the sound file it will play.
In the Browser choose Classes and expand KeyPoint. The first item under KeyPoint is *AmbientSound. Click that to highlightt it. Now pick a corner in your starting room and right click and choose Add AmbientSound here. You should get a little icon like this:

That is where your ambient sound will emanate from. Now we need a sound! In the Browser choose SoundFX. We now have to load a sound package. If you click on the Load button at the bottom you will get a window with lots of sound package files with the .UAX extension. There are lots of sounds in each package file. Choose one of the Ambient packages like AmbModern. You will notice that there are two sub menus for AmbModern: Looping and OneShot. They should be self-explanatory, but Looping will play and replay forever and one-shot is a single sound played once. For an ambient sound ( or background noise) you'll want a looping sound so choose Looping.

There are several looping sounds in the menu now. Click on one and press the Play button at the bottom. when you have heard enough press Stop. Find a nice ambient sound you like and highlightt it. I chose "comp1" for no particular reason. Now right-click your AmbientSound actor and open it's properties. At the bottom, expand Sound. Click on AmbientSound and then click Use and then the "..." button. A file name should appear in the field now. If it doesn't go back and highlightt the sound you want again in the browser and then try again. Your properties dialog should resemble this:

You should also hear the sound playing now. If you don't click the update real-time button in the 3D window (it looks like a little joystick). Note: this button will toggle sounds and texture animations, as well as showing invisible portals). You now have an ambient sound in your level! Let's give it a source. Go back to the browser and choose textures and load PlayrShp. Under Panel scroll down until you see a computer screen texture and highlightt it. Now build a brush 256 x 64 x 256 and place it against the wall. Add it to the world. You will want to change the side textures but leave the computer screens on the "front." Move the AmbientSound actor in front of the brush like below:

Now rebuild and run your level. The ambient sound of the computer noises should be playing and it should seem to be coming from the computer screens we added. As you walk away the sound should diminish and get louder as you approach the "computer." If something isn't right or you hear no sound go back re-trace the steps above. If you did everything right you will get sound (assuming the sound works on your computer!).

Triggering a Sound

Okay, we have ambient sounds now, but suppose I want a sound to play when a player does a certain action. How can I trigger it? Glad you asked, young apprentice! Sounds can be triggered and here is how:

You need 3 things to trigger a sound:

  • A SpecialEvent actor
  • A trigger
  • A sound (obviously)

First you need to decide where and what sound you want to trigger. As for "where" let's have it triggered as the player leaves the room.
In the Browser choose Classes and expand Triggers. highlightt (but don't expand) -*Trigger. Now right click at the entrance to the first hallway and add a trigger there. under the Trigger Properties, set an Event. Call it something cool and original like "sound1" without the quotes. Now in the Browser under triggers highlightt *SpecialEvent. We want the sound to come from behind the player as he leaves the room so add the SpecialEvent actor back in the start room. I chose the opposite corner from the "computer" we added earlier.
The SpecialEvent actor looks like a trigger with an ! on it. Set the Tag (under Events) of the SpecialEvent the same as the Event of the trigger (sound1 in the example above).

Now we need a sound. In the Browser choose SoundFX again and select AmbModern. This will be a OneShot sound. Choose "scream1" and highlightt it. Bring up the SpecialEvent Properties and expand Object. Set the InitialState to PlaySoundEffect.

Now expand SpecialEvent, highlightt Sound and click Use and the "..." button.

Rebuild and run your level. Now when the level starts you should hear the computer, and when you enter the hallway a scream should come from behind. You can trigger any ambient sound with this method. If you trigger a Looping sound it will play forever. This can be useful if you want a certain looping sound to start only after the player triggers it (like turning on an engine or something). The scream should play everytime you walk through the trigger. In a REAL level you would probably only want it to play once so you would set the Trigger property bTriggerOnceOnly to TRUE (under Trigger). There are times, however when you want a one-shot to play everytime it is triggered, for instance, if you had a wooden floor you wanted to creak everytime someone stepped on it.

Expanding Your Sound Control

Okay, we can make ambient sounds, we can trigger and ambient sound, we can trigger a one-shot sound. What else can we do? In the AmbientSound properties you will notice other fields like, SoundPitch, Radius and Volume. If you don't know what these do then play with the setting to discover. I could tell you but that would spoil the sense of discovery for you. :)

The Sound of Music

Someone I like and respect said to me: "If you're going to do a sound tutorial you might as well cover music, too." that is not an exact quote but that is basically what he said. So here goes: Music is too cool in a level and essential for a good single player level. The music in Unreal is cool and you can implement it very easily. In the Browser choose Music (oddly enough) and then Load. You will see the various music files that came with the game Unreal. You will recognize most of these. Load some into the Browser, highlight it and click Play to sample some. When you are through playing click Stop. Pick one you like. I chose EverSmoke because I like it.
To make Eversmoke the music for your level is too easy. Press F6 to open the Level Properties menu. Expand Audio.

Now make sure your music selection is highlightted in the Browser and highlightt Song and then click Use and "..." and your properties dialog should now have the Eversmoke file udner Song.

Now rebuild and run the level and when you start the music should be playing. Cool and easy, huh?

Changing Music

"But Wolf, after a coule minutes I'm sick of EverSmoke. What do i do?" You can change the music anytime in a level by adding a MusicEvent. In the Browser choose Classes and expand Triggers and highlightt *MusicEvent. Go to the end of your first hall in the 3D view and add a MusicEvent there. Give it a unique Tag (under Events) like "musicswitch." Choose Music in the Browser and load a new music file. highlightt it and then open the MusicEvent Properties. Under MusicEvent highlightt Song, click Use and "..." and the new song should appear in the field.

Now add a Trigger and under Events set it's Event to "musicswitch." Rebuild and run and now when you get to the end of the hall (the trigger) the music should change.

Music Mood

You can also use the music event to change the "mood" of the music. This can be a wonderful effect, especially in SinglPlayer levels. You do it by adding a MusicEvent and triggering it the way we did above. Choose the same song you started with and under SongSection selct 0 1 or 2. The slider goes to 255 but that doesn't matter. I beilieve there are 3 settings

  • 0 = base song
  • 1 = Tense/dramatic
  • 2 = action

Now, I may be wrong on those but try them and you sill see the difference. As you progress down the hall add MusicEvents and Triggers to change the music. Set them kind of far apart so you can notice the change. You can see that implementing these at key points and times in your level can truly enhance the player's experience. You can also Turn off the music with a music event by clearing the Song field and setting bSilence to True.
Try it. after adding the Song sectin changes, at the end of your halls add one to kill the sound.

Using Music and Sound

I can't stress enough how much music and sound can affect your levels. The right music at the right time can get a player's juices flowing and set the tone for the level and events going on around him. The placement and proper use of sound effects can make the atmosphere of your levels seem realistic and can totlly immerse a player in your level. Music and sound are essential parts of any good level and should be used wisely. too many music changes can distract the player and too many sound effects at once can be annoying. If something should only trigger once (scream, explosions, etc...) make sure they only trigger once. If something should make noise add an ambient sound near it and choose the proper sound for the experience (don't make a computer sound like bongo drums and and don't make electric sounds in ancient temples).

Sound and music can add a new dimension to your levels.

Good luck, have fun and as always, if you need further help, let me know.

-Wolf

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


The MusicEvent Actor

By : Joshua 'Techno JF' Fields

Reviewer for : http://www.unrealsp.org

Compiled location of actor: Engine.MusicEvent.
Location in Object Hierarchy: Object/Actor/Triggers/MusicEvent.
Function: when triggered, it causes the music heard by the players in the level to change. It also allows the music to be changed with a predefined transition type.

Configurable Properties
Variable | Effect
bAffectAllPlayers | If set to True, then every player in the level will hear the transition. If set to False, then only the player that triggered the actor will hear it.
bOnceOnly | If set to True, then after this actor has been triggered once, it cannot be triggered again.
bSilence | If set to True, then the MusicEvent actor will stop the music rather than playing the specified song. The various Transition types still apply.
CdTrack | This value specifies the track of an audio CD in the computer's CD-ROM drive. When triggered, the MusicEvent will cause this track on an audio CD to begin playing. The default value of 255 means that it will ignore this statement and default to the listed Song.
Song | This specifies the location of the music resource to access and begin playing (package and resource name).
SongSection | This number specifies the pattern to begin at when the Song starts to play. (Look further down the page for more information.)
Transition This value determines how the music should change between the current music to the piece of music defined in this actor.
  • MTRAN_None: the music will not make a successful transition.
  • MTRAN_Instant: the music will change instantly.
  • MTRAN_Segue: the two pieces of music will almost seem to overlap due to the quickness of the change.
  • MTRAN_Fade: the first piece of music will fade out before the second one begins.
  • MTRAN_FastFade: like MTRAN_Fade, but the first piece of music takes less time to fade out.
  • MTRAN_SlowFade: like MTRAN_Fade, but the first piece of music takes longer to fade out.

Tutorial:
To test this actor, all you need is a room with a Trigger and a MusicEvent in it (and the necessities, which are explained in the Beginner's tutorials). The room needs to be large enough that the player can move around freely without inadvertently touching the trigger. Set the Trigger's Event to the Tag of the MusicEvent, and put the Trigger in a place where you'll be able to both find it and avoid it. You can put the MusicEvent actor anywhere you want because its location is entirely irrelevant. However, most mappers put such actors in an area that is relevant to the actor's function, such as near the Trigger that causes it to work.

Once you have set up the room with all of the necessities, and the Trigger and MusicEvent properties are set up as you would like them, test this mini-map in Unreal or UT. You will notice that when you set off the Trigger, the music starts to play. Also, if you left bOnceOnly to false, then you can set off the Trigger again and the music will start over when you do.

Troubleshooting Question:
There are some music files in the original Unreal that don't play the tempo of some of their songs properly at times. I am not sure of the actual mechanics of the problem, but I do know both the cause of the problem and a viable solution. To more easily understand this fix, I suggest that you look up the Dispatcher tutorial in this guide.

To hear the problem more plainly for yourself, start by choosing a certain music package from Unreal. A few of the music packages that I have found this problem in are Nali.umx, UTemple.umx, and WarGate.umx. (Nali and UTemple have 2 songs each, while WarGate has 3 songs.) Choose one of these music packages for your MusicEvent actor, and choose SongSection 1 for it. When you test it, you will hear a noticeable drag in the tempo. Now, I'll introduce a method to correct it.

Leave the room set up as before, but remove the Event and Tag names on the Trigger and MusicEvent. Now, add a Dispatcher (also under Triggers) and a second MusicEvent actor to the world. In the second MusicEvent, use the same song as before, but choose SongSection 0 for it. Set the Transition property of this "Section 0" actor to whatever it was in your other one, and then change the Transition type for the "Section 1" actor to MTRAN_Instant or MTRAN_Segue.

Now enter the Dispatcher's properties and set up the first two OutEvents names to your "Section 0" tag and "Section 1" tags, whatever they are. Then go into OutDelays, and in the same place as the "Section 1" tag, change the number to 0.01 seconds. Before you leave, give the Dispatcher a unique Tag name. Close the Dispatcher's properties, and open your ordinary Trigger's properties. All you need to do here is make the Trigger's Event name the same as the Dispatcher's Tag name, so that the Trigger will go to the Dispatcher instead of the MusicEvent when it's triggered.

When you test the map and set off the Trigger, you might hear a small glitch at the beginning, but it's better than having the whole song ruined. Now I'll answer your question: "What did we do and why did it work?" The game won't play section 1 of these files incorrectly if section 0 is playing beforehand, so we make it do so. When the Trigger is set off, it goes to the Dispatcher. The first thing it does is trigger the MusicEvent set up to play section 0, but 1/100th of a second later, the Dispatcher triggers the MusicEvent set up to play section 1. The result is that the music at section 1 recieves the benefit of a proper tempo, since section 0 was playing beforehand.

*About SongSection: Music files that are tracked for the Unreal engine will sometimes contain more than one song. This setting is used to determine where in the file the actor should begin playing the music. In the music file, the patterns (phrases of music) from one song are kept separate from the others by using loop points. Usually, the patterns will be arranged so that the first patter of each song in the file is one of the first patterns in the file (i.e. patterns 0, 1, and 2, if there are three songs). Something to remember: the first pattern in any music file is always pattern 0.

Here's an example of SongSection that you should be familiar with if you've played any part of the Unreal SinglePlayer game. In the first Rrajigar Mines level, the first song you hear is SongSection 2 of DigSh.umx. After you cut the power to the force field, the music fades out into silence. A MusicEvent actor was used for this effect. When you face the first Skaarj Warrior in the game, the music instantly begins playing SongSection 1 of DigSh.umx. The music then continues through most of the level until it changes again to a quieter song, which would be SongSection 0 of DigSh.umx.

Also, there is currently no way to listen to all songs in a music package from within UnrealEd. To hear the entire contents of a music package, I suggest downloading a copy of ModPlug Player from www.modplug.com. If you have any interest in tracking music yourself, I would also suggest downloading ModPlug Tracker from the same location.


BB Drac - Unreal Tournament UED2 guide Sound and Music

Sound and Music

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

In this tutorial you will learn about sound effects and music.
First starting with sound effects and then music.

 Sound:
Sound effects should be used to aid the current design and will enhance the playing experience.

It can be activated / played in many ways and how it should be played.

The sound effect actors can be located in the actor browser under "KeyPoint".
"SpecialEvent" is however a trigger class actor and is located under "Triggers".

Sound Actor | Specific
AmbientSound | Play a sound effect, looping, constantly.
DynamicAmbientSound | Randomly play sound effects.
TriggeredAmbientSound | Trigger controlled ambient sound.
Special Event | Special trigger actor to play sound effect, single or ambient.
Property | Specific
+Sound |
AmbientSound | The actual sound effect.
SoundPitch | Pitch (speed) of the sound effect.
SoundRadius | Area affected by the sound effect.
SoundVolume | Base volume of the sound effect.
TransientSoundRadius | Never gotten to work.
TransientSoundVolume | Never gotten to work.

Using sound effects:
There is many places you add sounds.
Especially movers, ambient sounds and triggered sounds.

If you use ambient sound, which loops, you will only hear the sound
as long as you are in the sound radius.
In fact, the sound will stop when you are outside this radius and restart when
you enter.

Sound is also affected by movement and reverb.
Movement is what is known as doppler shifting and is determined from the velocity of
the moving actor.
(Any actor that have the Sound option can work like an "Ambient Sound" actor).

Reverb is explained later.

The last thing that affects sound is hardware support.
If you have the ability to set surround and/or EAX (Enviromental Audio) it will make
the sound play in different "strengths" for different speakers depending on
location.

Sounds are 'placed' in 3D and 'radiate' sound just like a light actor.
The sound volume will fade evenly to the edge of the radius.

From the two last sound properties it seems that you should be able to affect
how fast the sound fades, but I never got it to work.

 Ambient Sound:
With the Ambient Sound actor you play a sound effect constantly.
If the sound effect isn't looping it will automatically repeat it.

It should be used when you want a certain "background" sound placed
near things like machinery, fans, wind, water, water-falls and so on.

It will not "activate" or "deactivate" by a trigger and will play the sound
effect as soon as the map is loaded.

 Dynamic Ambient Sound:
This is a more advanced version of the regular "Ambient sound" actor.
It is used to pool some sounds and randomly play sound effects.

Under "DynamicAmbientSound" in the properties window is what is interesting.
bDontRepeat - After it have played one sound effect, it will not play any more.
bInitallyOn - If you need to trigger it to get it work or not.
maxReCheckTime - Max delay before actor tries a random check again.
minReCheckTime - Minimum delay before actor tries a random check again.
playProbability - Random chance of actor playing a sound, between 0 and 1.
Sounds[] - The slots for sound effects, up 16.

The random is a value between 0 and 1, meaning that 0.5 equals 50%.

Can be used to create more realistic / random sounds like traffic, computers,
machinery and much more.

 Triggered Ambient Sound:
It is supposed to play an sound effect (looping or not) when triggered.
The sound can be initially on or off.
It can also have different controls of initial state, like trigger toggle and
when trigger is "active".

For some reason it never worked for me.
If I figure it out I will of course update this asap.

 Special Event:
The special event, a trigger class actor, can be made to play a sound effect when
triggered.
By setting the correct Initial State you can control how the sound should be
played.
Please read the detailed description of the "Special Event" in the trigger tutorial.

Special events should not be made to play an ambient sound as this is what
the "TriggeredAmbientSound" actor is for.

 Reverb:
You can use the Reverd properties in a "ZoneInfo" actor to alter the effect of the sound.
To create such effects you need to set "bReverbZone" true.

By adding and adjusting the values under Delay[] and Gain[] you can make any sound
heard 'different' inside this zone.
More hollow, cramped, echo and so on.

My knowledge of sounds and how sounds work (in reality) is limited so I
really don't know how to set the correct values to create certain effects.

If I find some info. of it I will add it here.

 Speakers:
The amount of speakers and hardware(sound) present also affect how the experience
behind sound effects are for players.

This can be Stereo, Surround, EAX and much more.
UT support hardware surround sound and should be kept in mind when you place sound
effect actors.

 Importing / Exporting sound effects:
You can import and export sound effects in the .Wav format.
(8 or 16 bits 4kHz - 44kHz wavs are supported).

When importing you will need to enter "Package", "Group" and "Name".
The "Package" is what *.uax (file extension for UT sound package) it will belong to.
By entering "MyLevel" it will be saved along with the map.
The "Group" is simply what group inside the package it should belong to.
(Default is (All)).
The final is "Name" and that is simply the name for the sample.

If you save a sound package it will have the extension *.uax and must be stored
under "...UnrealTournament/Sounds/" directory.

If you use custom sound effects in a level and do not import them to the "MyLevel"
package, the *.uax package must be included when you distribute the map.

 Music:
Music in any level is what set the final touch.
It should consist with the current theme and set the mood for players.

Music in UT is of 'tracker' format which means that it is sample and pattern based.
(Old Amiga folks should know what I am talking about).

A pattern is divided into multiple channels and for each channel you can play a
number of samples.
All in all, a tracker (or Mod[ule]) is a series of patterns, playing samples
in different notes.

This is a very simple and easy to handle as you can create and use what samples
you want, in contradiction of MIDI or MP3.

To work and create tracker/mod music you need a tracker program, like
Fast Tracker, Impulse Tracker or Pro Tracker (Amiga?).
(Most of it available as shareware/freeware).

 CD Music:
I must admit that I haven't tested using CD music in a level, but it
should work the same way as regular music but using the CD selection options
instead.

 Importing music:
Now that you know that UT use tracker format you probably wonder
what you need to import music.
The music format must be of Tracker type and that would be *.Mod, *.It, *.S3M and
a lot more.
(Might even be able to import tracker music not listed in the file format).

 Exporting music:
You can also export music by simply selecting the song and then
"Export..." from the file menu.
You are only able to export it to the *.S3M format.
(S3M is supported by WinAmp).

 Music Events, In-game:
In any stage of the game, you can change the current state of the music.
The "MusicEvent", part of the trigger class, can be used to change the song,
turn it off and more.
(See my trigger tutorial for details of the "MusicEvent").

Considered that you can change the section of a song with a MusicEvent
some issues might be worth knowing.
As music is Pattern and Sample based the song might not sound good
if you jump to a section (pattern) and a specific sample hasn't been
played yet, missing out on some sounds.


BB Drac - Unreal Tournament UED2 guide Music list

The Music List

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

This is a complete list of all original UT songs that came with the CD.

I have also listed type of song and where they suit.
This ofcourse may not apply to you.

Each song is listed with words separated with commas and what kind
of gametype they suit best.
The first word represent how the tune goes/feels.
Second is what kind of map/look it sound good to.
The last word is the song tempo or what it is like.

Song | Specific
Botmca9 | Slow, Space, Mood (CTF, DOM, AS)
Botpck10 | Funky, Base, Action (DM, DOM, CTF)
Cannon | Deep, Ancient, Action (DM, AS)
Colossus | Heavy, Military, Action (AS)
Course | Funky, Space, Action (DM, DOM, CTF, AS)
Credits | Powerful, Military, Trophy (AS) (Name: Trophy)
Ending | Short, Military, End (Possibly AS)
Enigma | Calm Deep, Tribe, Mood (CTF, DOM)
Firebr | Deep, Base, Action (CTF, DOM, DM)
Foregone | Deep, Space, Mood (CTF, DOM)
Godown | Fast, Spaceship, Action (DM)
Lock | Funky, Ocean, Action (DM)
Mech8 | Fast, Outside/Base, Action (DM)
Mission | Powerful, Base, Action (CTF, AS)
Nether | Slow, Underwater, Mood (DOM, CTF, AS)
Organic | Wierd, Alien, Action (DM, DOM, CTF)
Phantom | Special, Outside, Mood (DM, DOM, CTF)
Razor-ub | Powerful Deep, Heavy Fort, Action (DM, AS)
Run | Fast, Space, Action (DM, DOM, CTF, AS)
Saveme | Fast, Space Base, Action (DM, DOM, CTF)
Savemeg | Fast, Space Base, Action (DM, DOM, CTF) (Almost as Saveme)
Seeker | Slow, Underground, Mood (DOM, CTF, AS)
Seeker2 | Slow, Underground, Mood (DOM, CTF, AS) (Almost as Seeker)
Skyward | Slow, Space, Mood (CTF)
Strider | Paced, Military, Action (AS)
Suprfist | Fast, Base, Action (DM)
UnWorld2 | Powerful, Fantasy/Underground, Mood (DOM, CTF)
Utmenu23 | Calm, Outside/Base, Action (DM, DOM)
Uttitle | Calm, Outside/City, Mood (AS)
Wheels | Calm Deep, Swamp/Jungle, Mood (DM, DOM, CTF)


BB Drac - Unreal Tournament UED2 guide Sound list

The Sound List

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

These are some of the sound packages from the the original UT.

Package | Specific
Activates | Beeps, Clicks and Machinery
AmbAncient | Monk, Lava, Fire, Glass, Explosion, Ghost and Creak
AmbModern | Alarm, Fan, Electric, Hum, Machine, Pipes, Teleport and Scream
AmbOutside | Animals, Waterfall, Swamp, Waves, Lightning, Quake and Thunder
Announcer | Announcer Voice
BossVoice | Boss Voice
BotPack | Weapon and Item Sound
DoorsAnc | Thumps, Chain, Stone and Wood door sounds
DoorsMod | Modern Door and Lift sounds
Female1Voice | Female 1 Voice
Female2Voice | Female 2 Voice
FemaleSounds | Female sound effects
Male1Voice | Male 1 Voice
Male2Voice | Male 2 Voice
MaleSounds | Male sound effects
Pan1 | Helecopter, Train and some Voice
Rain | Rain and Thunder
Vrikers | Voice sounds


deCyber Build Section

Music

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Contents

1) Adding your music
2) Triggering music within a level
3) Importing Music

Introduction

Although UT doesn't really support SP games you can make them, and as such I'll base this tutorial around that. By covering SP level building you can cover any music needs required by any game type.

Adding your music

To assign music to your level just do the following:

1) Select the "Music Browser" from the top icon toolbar (it looks like a musical note).

2) From the new window that appears choose "File" and "open". A browser will appear from which you can choose any music file you like. Once chosen, it will appear in the window. Click on it once so that its highlighted (double click it to actually hear it).

3) Back in the main editor screen right click in one of the grids and select "Level Properties"

4) A properties menu will appear. Click on the section called "Audio"

5) A further set of menu options will appear. Click in the area called "Song".

6) Now click the "use" button in that field and you should see your music selection appear there.

7) There's also a field there called "SongSection". This is set to 0 by default. Most of the music for the original Unreal is split into 3 sections. Section 0 is the main tune. Section 1 and 2 are suspense and action sequences. This is useful to know if you're fed up of hearing "Warlord" all the time for fight scenes!

8) Save your level and try it. It will play the music straight away.

Triggering music within a level.

Typically there are two reasons why you would want to trigger music in a level. Firstly, the player might enter an area, which is somehow different, and you want to change the atmosphere. Secondly (most commonly) a battle is about to start and you want some aggressive music to start the adrenaline pumping. Most of the time you wouldn't use this in a Deathmatch, Domination or Capture the Flag map, but you may want to use it in an Assault map and you wourl certainly want to use this in a single player map.

Just follow these steps
(assuming you have a level prepared which you want to add it to):

1) Open the "ActorClassBrowser".

2) Select "Triggers" from the menu.

3) Select "MusicEvent" from the extended menu.

4) Right click on your map (in the 3d picture) anywhere you like. Its probably best to keep it fairly close to the area where the music will happen so its easy to find it if you want to change it. You should see a grey animal head appear in your map

5) Now open the Music browser.

6) Click on "File" and "open" and from the browser choose the music file you want. Then highlight it once it appears in the toolbar.

7) Click on the music event which you added to your map and press F4 to bring up its properties on the screen.

8) In that properties menu click on the field that says "MusicEvent"

9) Choose the field that says "song" and click "use" and your chosen music will appear there.

10) There will also be a field with a drop down menu called "Transition". From here you can choose if you want the music to slowly fade in or chop in instantly. For fast fighting music, use "instant" and for moody areas use "slow fade" You'll need to experiment with this, otherwise the transition can sometimes go "choppy" when it changes in the game.

11) The "song section" field enables you to pick a part of the music file to use. A lot of the music files are split into 3 sections.

0 = ambient or mood music
1 = suspense
2 = action

12) Now you'll need to "label" your music event so that UT knows where to look when it has to change the music.
Still in the properties menu, click on "Events". And in the "Tag" field call it "Vibes" (or whatever you like).

13) Now you need something to trigger your music off when you play. This could be any number of things. It could be a simple trigger (taken from the classes menu, under triggers). It could be a mover of some kind. Pushing a button may cause a set of events to happen, and one of those events could be your music. Another common way to start music (usually the fighting stuff) is to have a monster start it off.

Here's the general principal to trigger your music.

Let’s say you have a Titan, and when he sees you, you want the fast music to start. All you need to do is select the Titan and bring up his property menu. Under the menu option labelled "AI", you'll find a field called:
"FirstHatePlayerEvent". Type in "Vibes" (or whatever you called your music), in that field, and as soon as the Titan sees you, it will trigger off the music.

You can also have another music event, with the Song selection set to "None" and the transition set to "fade".
Give it the tag name of "dead" and in the Titan's event field type "dead". When the Titan dies, the music will then fade back out again.

For movers, it’s simpler. In the "event" field type in "vibes" (or whatever you called your music tag) and the mover will start the music when it reaches its final keyframe.

For straightforward triggers, just put "vibes" in its event field.

To get rid of music all together use triggers in the same way, but set the property "bSilence" in the "MusicEvent" property to true.

And that should be all you need to know to have music in your levels.

Importing Music.

Importing music is tricky business and you will need a useful tool to
convert files into a format that Unreal understands.

Unreal Tournament will not import WAV files as music, so you will need to convert these if you have them. A useful tool for doing this is Modplug: http://www.modplug.com/
Once you've loaded your WAV file in there, all you need to do is "Save as" and use one of the compatible formats it lists! Then you're ready to import!

Essentially, all you need to do to import music files is to open the Music browser click on "File" and "import" and use the browser to find your piece of music. When you open it, the music will appear in your music browser window, and then you can save it as a UMX file.

EZkeel
(Simon West-Bulford)


deCyber Build Section

Sounds

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Downloadable files : Sounds.UNR

Contents

1) Ambient Sounds
2) One Shot Sounds
3) Random Sounds
4) Importing Sounds

Introduction
This is quite a basic tutorial, as I don’t know an awful lot about sounds. I know
enough to add atmosphere to maps and use my own noises, but that’s it.

Ambient Sounds
Another essential addition to your level are the ambient sounds which your player will encounter. A good visual effect will seem even more impressive if you have the appropriate sounds to go along with it. However, fast paced gametypes won't benefit from this much as players don't generally stop to listen to birds tweeting while a redeamer is about to turn them into jam!

To add ambient sounds to your map, just do the following:

1) Create a lit room with a playerstart and set the gametype to singleplayer so you can run around in an empty room to bask in your audio glory. Then choose "Keypoint" from the "ActorClassBrowser".

2) Under the "Keypoint" option you will find some more options. Choose "AmbientSound" and add this item to your room. You should see an object appear that looks like a box with a key on top.

3) Click on this item and press F4 to bring up its properties box.

4) Click on the sound option and as in the diagram on the left and you will see a few fields that you may want to change.

5) You will need to tell it which sound you want, so open up your sound browser from the icon tool bar at the top (looks like a small wav file icon) You’ll see a list of different folders appear, but they may not have the type of sound you’re looking for.

6) Click on "File" and "open" and then choose one of the sound files from the browser. For this exercise choose "AmbOutside.UAX". You will notice that you have a choice of "looping" or "one shot" sounds. You can choose either selection, but its best to choose "looping" for ambient sounds (its set to this by default anyway).
(If you choose a "one shot" sound, it will loop anyway).

7) From your list of sounds, choose "wind31" and in the "AmbientSound" field of your property box that should still be showing click on it and then click on "use". The chosen sound file should now appear in this field.

8) You can also change the number in the "SoundPitch" field. Experiment and you will see that it makes the sound seem deeper or squeakier depending on how high or low the number is. The maximum number you can use is 255.

9) The "SoundRadius" will enable the sound to be heard from further away the higher you have the number. The widest radius is 255. If this still isn’t loud enough, try duplicating it (CTRL-W), so that you have two of the same ambient sounds in that area.

10) Similarly, the sound will be louder, the larger the number you use in "SoundVolume". Again 255 is the largest number.

11) I don’t know what "Transient Sound" does. :-o

One Shot Sounds

There may be occasions when you want to trigger off a quick sound You're more likely to use this for deathmatch games), like an owl hooting, an earthquake sound or an explosion. For this you will need to use a "SpecialEvent" trigger.

See the tutorial on TRIGGERS to find out more.

Random Sounds

For a good atmosphere in maps, its useful to have one shot sounds that pop up from time to time. To do this you need to use an actor called "DynamicAmbientSound" which you will also find in the Keypoints section. If you want the sounds to play straight away set the "bInitiallyOn" field to true.

MaxReCheckTime is the maximum amount of seconds you want to pass before another sound must be played. This ensures that you don't get occasions where you haven't heard anything for ages.

MinReCheckTime is also in seconds and forces your sounds not to play too often. Once a sound has played it must wait for at least this length of time before another is played.

PlayProbability refers to how often it plays a sound. The number must be between 0.1 and 1. The higher the number, the more often you will hear a sound.

Finally, put whichever sounds you want in any of the 16 sound fields but don't use looping sounds because they won't shut up once they've started!

Importing Sounds

In case the sounds that are in UT don’t give you the effect you’re looking for, if you just want something different, you can actually introduce your own sounds to UT.

Just do the following:

1) First create the sound that you want with whatever package suits you. The sound must be in the correct format or UnrealED will import it, but crash if you try and use it! I found it worked as Mono, and 22050Hz.

2) Open the sound browser, and then click on "File" and "open". Choose a small UAX file from the browser such as "Extro.UAX".

3) Now Save this UAX file as a different name, e.g. "Noise.UAX". Once it has saved, it’s a good idea just to load it in again so that "Noise" is actually showing in the browser.

4) Now click on the import button, and another browser will appear. Select your sound file and click OK. A small box will appear with Name Group and Package on it. "Name" will be whatever you want to call your sound, the "Group" will be looping or one shot, or another unique set that you want to create. "Package" is the name of your UAX file. In this case, it should say "Noise".

5) If all that looks right click on OK. You should now see your sound file appear in your right-hand toolbar. To make sure it works, double click on it and you should be able to hear it. If not then you’ve got a problem, try again!

6) If its working, you now need to remove all the sounds included in this file that you don’t need (i.e. all the sounds that were included in the original Extro.UAX file). Remember that there may be more than one group (looping and one shot). You need to remove all the sounds from all of these, so that all that remains is your own sounds. If you leave them in, it won’t hurt, but it makes your file unnecessarily large (UAX files are big enough as it is!).

7) That’s it, you should be able to introduce your new sounds in your level using the methods above.

Be Noisy.

EZkeel
(Simon West-Bulford)


Unreal Music

by [SAS]Roswell

Roswell@gamerplanet.com

Overview:

The mysteries of .umx part 1

Forward:

This is my first tutorial. You can hear some of my work on the new total conversion for UT called SAS: Into the Lion's Den.

Content:

Creating music for Unreal and Unreal Tournament can be one of the most rewarding experiences one will have in creating original game content. That said, it's also more tricky than it appears. Unreal Tournament uses a proprietary file type, .umx , to store music for the game. During your first searches on the internet, most realize very quickly that there is no utility to create a .umx file. This fact alone is prohibitive of many aspiring music gurus creating original tunes for Unreal games.

UMX Exposed

In reality, there is nothing mysterious about .umx files. The .umx extension is merely a designation given by the crew at Epic Games to any number of mod files.

Okay, But What Is a Mod File

Mod files are created by what is known as tracking software. As a general rule, the beauty of mod files is that they allow would-be composers easy access to layering via looping music tracks at points of repetition. (This is the reason you'll often hear the same backdrops in Unreal Tournament music, but with additional insturmentation added each time it is played.) This function, however, can also prove quite frustrating for those who wish to have complex song structures in Unreal Tournament. Many of my first attempts at game music were rendered useless because of this "feature". The sad truth is that many (including myself) feel that Epic Games (and other licensees of the engine) made a horrible mistake not enabling the Galaxy audio engine to recognize .mp3 or .wav content.

About:

E-Mail Roswell: Roswell@gamerplanet.com


Unreal Music

by [SAS]Roswell

Roswell@gamerplanet.com

Overview:

The mysteries of .umx part 1

Forward:

This is my first tutorial. You can hear some of my work on the new total conversion for UT called SAS: Into the Lion's Den.

Content:

Preface

As discussed in my previous tutorial, the Galaxy audio engine in Unreal Tournament uses mod files for in-game music. Mod files are created using "tracker" software, most of which is available free for download on the internet.

File Types

As mentioned in my last tutorial, the .umx file extension actually encompasses several tracker file types. Unreal Tournament supports .it (impulse tracker), .s3m (scream tracker), and .xm (fast tracker) files, to name a few.

Choose Your Weapon

Unfortunately, many solid tracker programs are DOS-based. Although there is nothing inherently wrong with DOS-based programs, the interfaces of these programs often "feels" uncomfortable. This compounds the problem that trackers, in general, are NOT intuitive.

All the file types listed above (.it, .s3m, and .xm) are the native file extensions for their respective tracker programs. [Doing a search on Google (http://www.google.com) will yield multiple download possibilities for each.] That said, this also makes each of these programs (Impulse Tracker, Scream Tracker, and Fast Tracker) somewhat limited. Although the properties of these files should be the same (they are all mod audio), differences in loop points and quality often become apparent after only limited experimentation.

The real solution for in-game audio would be a tracker program that encompasses all the file types you're likely to want to use. Thankfully, ModPlug Tracker (free for download at http://www.modplug.com) is just such a program. An added bonus is that it's Windows-based (thank God) and even runs well on Windows 2000! ModPlug converts file types seamlessly (it basically just changes extensions) and offers a wide variety of tools. (You can catch screenshots in the upcoming tutorial "Mastering ModPlug".) Frankly, I wouldn't waste my time on anything else. Although there are benefits to other tracker software, they are somewhat time consuming to learn, and there isn't alot of readily-available information about them on the internet. (And when you do try to get help-- most of the audio gurus on the message boards assume you have this program and will slap you with the proverbial large trout if you don't have it.)

About:

E-Mail Roswell: Roswell@gamerplanet.com


By

 Music Files in the Unreal Engine

By: Tyler Boyd
shapeshiftr@gridusa.net

I've seen so many questions about UMX files and how they work on forums, I've decided to release a tutorial about it. This is very broad, and has more to do with PC audio in general than with Unreal editing, but I think it will be a useful tutorial when thinking about importing new music.

I've written this in response to some of the posts on the forum about importing your own music. I'm going to try to make this as in-depth as I can, so I may go off-topic, but this is just to give you a better understanding of what I'm talking about.

From what I've found, there are 3 types of computer audio. These are known as WAV, MIDI, and MOD. WAV is pure audio: the actual waveform that describes any sound clip. A WAV could be a voice, a beep, a guitar, or even an entire song. WAVs are generally very versatile. They come in 8 or 16 bit, Mono or Stereo, and basically any kHz quality value you can think of. You can edit them to your heart's content, adding effects like echoes, cutting and pasting portions of them, anything. WAVs are the ideal file format for any small sound effect or one-hit pad or instrument, but if you have a 5-minute, perfect-quality WAV file, you get terrifying file sizes. WAVs' file sizes are directly proportionate to their quality and length. Now, there is an exception to this rule: MP3s. They are a kind of extremely compressed WAV file, and that's why a 4-minute MP3 song is normally about 4 or 5 MB.

MIDIs are a lot more complicated. A WAV could be compared to the sound of a violin or a trumpet playing one note, but a MIDI could be described as a musical score to conduct the entire orchestra. This is why they are much much smaller than WAV files. If your computer supports MIDIs, it contains a sound bank of tiny WAV files. These WAVs are single blasts of trumpets, flutes, guitars, drums, anything you could find in a normal orchestra with some extras. What a MIDI file does is tell the computer to play these WAV files in a sequence(MIDI files are also called sequences). A MIDI file is a set of directions- that's all. The size of a MIDI file is directly proportionate to the amount of complexity to the song. The Mission Impossible theme MIDI would be a larger file size than, say a single note held out for an hour.

Now, MODs- the focal point of this article. A MOD is basically a self-contained MIDI. In essence it is just like a MIDI- it tells the computer when and how to play certain WAV files. So why aren't MOD files as small as MIDIs? MOD files actually contain the WAV files, or samples, to be played. Aside from UMX, there are four general types of MODs: MOD, XM, S3M, and IT. WinAmp can play all of these but NOT PERFECTLY. The bulk of a MOD's file size lies in the WAV files it contains. If you have 40 megabytes of WAVs contained in MOD, it won't matter if it's a 2-minute or 2-hour song. You'll still end up with about a 40 MB file size.

Now for the part you can actually use: You shouldn't convert a WAV file to UMX unless it's short and of terrible quality. And converting MIDI files to UMX isn't such a bad idea provided you do it correctly and maybe enhance it a little bit. I suggest that if you want to use custom music, you create your own in with ModPlug or another tracker.


Provided by

 The Floor Lofter

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

The Floor Lofer

The floor lofter can make a great difference to your levels. It is actually a great little device that I have not used to much before, but the other night, I started to fiddle with it and managed to get some terrific results from it, and I have had quite a few questions about natural levels of late, so what better way to show you how to do them, then with a good explanation of the Floor Lofter.

The floor lofter can be accessed by a menu from the "window" option, and it opens a new little window. When you open the window, you will see a "box like" frame of a brush, with five dots on the top of it. There are a few other things here as well, but these will be explained in order in a few moments. You will see five dots. Each of those spots represents a different level that can be changed to suit your needs. The best way to explain how it works is to pretend that the whole thing is a cake for a little while. You will be cutting the cake into a few separate slices. The first bit that you are looking at is the end of the cake side on. You can change the eight of the "topping" here by moving the dots up and down. When you have created the first layer of the cake then you can start to move on to the second section of the cake. At the top of the screen you will see a section that says 1 of 5. and there will be a few arrows next to that. Click on the right arrow and you will see it click over to 2 of 5. You will find that the dots have moved to the middle again. To start making your second section of the brush, move your dots up and down again, and you will have created the second section of the brush. Keep doing this until you have got all of the parts (There are five in total) and click on the "create" button. You will see the new screen close, and your builder brush will be in the shape of your new creation. The brush will be in proper 3D and will be able to be used just like any other brush in the editor.

Note : You can create a brush that is much taller then the normal one that it will automatically create by dragging the bottom of the brush down, and you can actually drag the dots up over the limit of the screen that appears. You are also able to create brushes that will match one another by writing down the vectors that the dots take. You can find these out by letting the mouse hover over each one. To make a longer brush, simply make sure that the 5th line of you first shape and the 1st line of your second brush are set to the same numbers. The same can de done if you want to have a brush (or landscape) that is wider then the standard that the brush is. You can actually change the size of the brush that is created, and you can then scale the brush up and down when you take it back into the editor, although if you scale it up, then you will obviously lose the detail in it, so you might have to do a little math to make the brushes align properly when you get them back into the editor.

This should about wrap it up here, although as I said, I have really only used it in the last few days, if there is something here that I have not explained, then please write to me, and I will try to make things a little clearer, or if you want to add to this tutorial, then please feel free to do so.


Wolf's Tutorial Floor Lofter

Wolf's Tutorials: The Floor Lofter

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

The Floor Lofter

Introduction

This is the fourth in a series of tutorials from Wolf. If you are a beginner to UnrealEd it is suggested you go back and read a basic tutorial and then the first three in this series. This little tutorial will introduce you to the Floor Lofter.

Part One - The Floor Lofter

The Floor Lofter is an experimental program built into UnrealEd that will allow you to quickly and easily allow you to make a natural looking outdoor surface for your Unreal maps. It am sure it can be used for other structures as well, but natural looking terrain is it's strong suit. The Floor Lofter can be found in UnrealEd on the menu at the top under Window. Open the Floor Lofter. You should have this screen:

Now, if you were to just hit Render you would get a brush like this:

Basically, a cube cut up into 16 sections. If you check out the options across the top

it looks like there are several. Most, I believe, are not implemented as they seem to have no effect.

Here is the option and what it does:
Render Button - builds the (red) brush as per the rest of the settings.
Level - there are five levels of lofting, they go across the brush from left to right (in the overhead view).
Terra Grid - sets how many "blocks" there are across. The default is 4 x 4 and even if you change it, it has no effect. This is not implemented.
Cell Size - This sets the size of each block. Again, this is not implemented.
Render Scale - default is 1 which make the over all length and width of the brush 256 x 256. As you scale it up it increases the size of the brush accordingly.

Common Ground

Lets just show you what the floor lofter does. Start by loading the GenEarth.utx textures. Now, select a rocky one you like. Set your cube to 512 x 1024 x 1024. Subtract this brush, building a "room." Now choose a grassy looking texture for the ground. Think about how "hilly" you want your ground to be. Don't get too carried away yet, this is just a tutorial! Open the Floor Lofter. First of all, see that red line near the bottom of the window, that is going to be the bottom of your brush. The line at the top (with the vertices) will be the top of the brush. You can click and move that run line up and down to set the thickness of the floor brush. You can also click and move the vertices (and thus the lines of the top of the brush) and the top. By doing this you make hills and valleys, or high and low spots. The farther you raise a vertex on the top line, the higher the hill, and the lower you drag it toward the red line, the lower it will be. Do not drag a vertex from the top line below the bottom red line! You'll only crash and burn.

Now after you set the first screen the way you want it, then click on the "next" button [image] and go to the next level of lofting. There are five levels to set. Once you have set your terrain in all five levels, click the render button and then close the floor lofter. You should have something like this:

You can see this brush doesn't come close to filling our area. There are two things we can do. One is click on the "scale" button and stretch the brush till it fits. The second is to go back into the floor lofter and start again, but this time BEFORE we click the render button, we'll set the scale. Since our room is 1024 x 1024 we need to set the render scale to 4 (remember it starts off 256sq and we have a room 1024sq, and if we divide 1024 by 256 we get 4). This should fit our room very well. Now, the hills may be a little tall for this scale. If you think they are, just re-do them, keeping in mind the scale.
Note: you have to set the render scale each time you open the floor lofter. It doesn't keep that information.

When you get a floor brush that looks good to you then line it up with the bottom of your "room" and add it to your world. Now you might note that the scale of the ground texture is a little stretched. That's because UnrealEd "stretches" a texture to fit the surface of the brush. To fix this high light a face of the ground and press SHIFT-T (this will select all the matching textures in your level). Right click and go to Align Selected and align as floor/ceiling. This should reset the texture. If all went well, you should have a ground something like this:

As you fly through your level in the 3D window you can see how big (or how little) your hills are. Keep this in mind when making terrain. It's very simple: the higher you want the hills, the more you move the vertices.

Experimenting

You turn to play with the floor lofter! Remember, it's experimental so be careful and always experiment on a new level and not one you intend to keep. If, while you're playing around, you make an absolutely wonderful floor brush you just have to keep, export it like we did the brushes in the previous tutorials. Try new things, like only moving the vertices in one (of the five) levels to see what that does. Play with it and be creative and have fun!

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


Natural Landscapes

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

    Natural Landscapes

    Natural Landscapes seem to be what everyone wants to do when they are creating an outdoor level, so I best be having a little talk here and talking about some of my own methods of achieving a good looking level. I do have a few tricks here that I will explain, but a lot of it is simple technique that has been used and grown from simple editing. I mainly use a technique that grows slowly using the basic primitives and then manipulates the brushes, and adds in more brushes until slowly the main object that we are trying to create grows to look natural because of the irregularity of the brushes, then once that has been done to a level that we are happy with, an intersection of the entire brush will be made and the new builder brush is used to create a realistic looking mountain or cavern or whatever in the place where we want it.

    To start with I think that an example of how I created a damn good looking cavern will do the best job of explaining all the rambling that I have done so far. I needed a cavern to look like a natural cave in one half of it (The level is actually for the up and forthcoming Mionions of Evil TC). I needed a cavern with a realistic looking rock-fall and a waterfall flowing over the rocks and into a nali-made pool of water. I started off deciding just how big my room would have to be, then added a little "play" on each side so that I would be able to add in extra crevasses with a realistic amount of ease, rather then toying with additional brushes that would have to be subtracted. When I had decided upon the actual size of the room (about 1024x2048x1024 if you are really interested) and I made this room off a little from the level. This was then where I was working the most with all the additional brushes that I would be using. It is much better to create something like this off from where it will actually be going, as it then allows you to "test it out" by doing an intersection and putting it into the level before you have to delete any of the older brushes. Ok, getting back to where we were. I then created a few "base" brushes. I wanted the rocks to look as natural as I could, so I made a basic cube brush, then intersected it against the wall of the room, until it looked fairly realistic. This was actually fairly easy, as I simply rotated the brush so that all the main angled sides were overlapping against the wall, then did an intersection to get rid of it, and rotated it some more, then did another intersection and so forth, until the brush no longer looked like a cube, but a boulder. When it did look like a large rock, I put if off to the side, and added it to the world, so that it would not go anywhere and I could use it over and over again if need be. I then made another cube and followed the steps above until I had another boulder although I made sure that it looked different to the first that I had made. I kept this up, until I had made about four or five (I can't remember exactly how many) and they were all sitting nicely off to the side of the room. When I was satisfied with what I had for base brushes, I "drew" the entire inside of the cave inside my head.

    Then with the brushes that I had made, I started to build the cave little by little, and made sure that I intersected the brushes EACH time before actually added it to the world. This was quite important, because if you didn't do this, then you would actually be causing horrible BSP holes (If you are not sure what these are, please look up the Jargon tutorial) and then most likely create a HOM effect. Slowly as each of the brushes was added, the cave interior was beginning to look more and more like a real cave would look. To stop the repetition as I was only using a few main brushes I was rotating the side that would be visible all the time, and also changing the size of the brushes so that if I did have the same faces of the brush showing, I would not have them the same size as well. Even though this was fairly tedious and did take a long time for it to be as good as I wanted it to be, the final product was nothing short of "real". When I had finished creating the actual rocks that would make the "fallen in" section of the room, I was ready to start adding in the pool and the water. Using the 3D view of the editor, I made completely sure that I would have no holes in the bottom of the pool and the sides of the pool, so that I would be able to create a sheet of water, and safely place a water zone below it. I had to "patch up" a few holes that were there, and I also made (I got a little carried away here, and I admit that freely) a little rock fall or "rapids" for the water to flow into, then finally I made sure that the "water level" would be as natural as possible by adding in a few extra rocks to make sure that the pool would look as natural as possible. When I had made the actual sides and interior of the pool, I added in the nali-made pool edge, which was made from a cylinder (I think about 40 sides) and hollow. I made it to be an elongated shape by simply stretching one plane of the shape so that it would grow longer, but nothing else. When I had the right shape built, I intersected the brush and found that I had the brush just to the exact dimensions so that the water would flow easily and freely into it like a real water would flow. When this was complete and I had the brush textured and just what I wanted it to look like (still without a drop of water though) I did an intersection of the entire room, and placed it into the level where it was supposed to go. I then saved the level ( Something that you should do as often as possible) and started to work out how to create the water itself.

    Who ever said that water had to be made from a sheet? I think that this is a great misleading theory that everyone seems to have. I actually used a cube and like I was making a boulder, slowly intersected to and from the brush until I had the red builder brush looking just like the water would look when I had finished. This was done in a few steps, as it was simply too much work to create the entire brush from a single brush, so I made a few brushes and created them in a way that they would overlap each other, and the player would not be able to see where any of them did actually meet. The fact that I was using a solid brush here also made the job a lot easier as it allowed me to work within a finite space and not work with a sheet that would intersect poorly, if not all the edges were surrounded. I finally managed to create the brushes that would make the water and placed them into the level just like I would place water normally. I prefer to create water so that it actually flows, and so I went to each individual facet of the water, and made them "flow" downward, even though thus did take a lot of playing about and changing the individual directions of the faces and changing the panning scale. Finally when they all looked good enough so that I would be happy with them, and then I placed in the water zones where I knew the player could reach without cheating. I actually did leave a few places there that were not filed with water, but this was simply because it would not be possible for the player to get to them and so placing water into them would simply add to the resource list that would have to be filled, and it would slow down the level just that little bit more.

    Finally I added the lighting to the the cavern and did a final rebuild and then then cavern was complete. There is no "one" way to do natural landscapes and rocks, but this should be a good and reliable way to create very realistic looking rock formations that will look really good in your levels. If you want to add to this tutorial, then please email me, and I will happily add useful comments to this, and there is simply so much to cover, and what I have done here is simply one method of doing rocks.


Natural Rivers

by: Tomasz "Millennium" Jachimczak

tomasz@planetunreal.com

unrealed.exe

Natural looking water is tricky to do, but there are ways that it can be done if you follow a few simply steps and have a little patience. This tutorial will be somewhat vague at times, but that is becuase I am trying to get across a method, which will change with each river that is being done. If you have read the "Landscapes: tutorial, then you will find that it is very similar to that one, but if you have not done so, then read these notes carefully.

Rivers are certinly not "straight" and to make them look irregular and natural, you will need to take quite a bit of time and effort, but the reward will be worth the effort that you put into a level. When you have worked out the main section of the map where your river will be, make another room of that size somewhere off to the side of you level, and then start work there. The first thing you will want to do is to cut out the basic shape of the river, but when you are doing this, please make sure that you leave a fair amount of room off to the sides, as you will be cutting more out later with different brushes. You should make a basic "river" out of simple cubes and brushes. When you are cutting this basic shape out, make the cubes or brushes that you are using here about 1/3 the actual width and about 1/2 the depth of the river that you want when you finish. When you have the basic shape cut out of your river, make a "wedge" shape froma brush and add it to the level somewhere near the river. Then create another brush that is wedge shaped but a little rounder. Place this somewhere off to the side as well. Create another brush that is "rough" and look like it is full of bumps and keep this for later use. When you have made these brushes, you will be able to move on, as they will now become your basic brushes to create a water way with.

Using the "rough" brush cut further into the river bottom, to give it a rough and "real" feel to it. Don"t go too far over board here, as if you create too many polygons, the level will play somewhat slowly, but keep in mind that the more you use, the better it will look. It will be up to you to decide how many polygons you are going to use depending on the complexity of you level in general. If you have the river as only an addition to the level then you will want to try to keep it as simple as you can, but if you are creating a river as the main section of your map (Possible if you are doing a boat ride or something like that) then you will most likely want to go into some really high poly counts to make the level simply breath-taking.

When you have cut the bottom from your river, change to one of the wedge brushes, and start to create a river edge for it. By putting the narrow end of the wedge, you will be able to make the edge of your river very shallow, and have it getting deeper as you get further in towards the middle. The wedge brush should be scaled so that it will meet the rough bottom and be just sharp enough to get to the surface of the river and not appear either too deep or shallow. As you are cutting away, with the brushes here, make sure that you are constantly intersecting, otherwise you will end up with horrible BSP holes and also your river will not look quite as natural. When you have made some of the river edges, use the rounded brush to add in a few little "pools" ow water with the brush near the sides and the river should be just about complete. The only thing that you will no have to do is to do an intersection of everything where the river is, and then place it into where you will have the river in the "real" map. When that is done, add in the actual water itself by intersecting a sheet of water. If you can do this with one brush, but if that is not possible then you will have to match them up VERY closely, otherwise you will not be able to put water below the surface due to a hole somewhere.

Like I said, this is most likely somewhat vague if you have not tried to do something that looks very natural before, but with a little practise, you will be able to make very realistic and natural looking water-ways and your levels will have that little extra added to them


Provided by

 Some Thoughts on Out Door Techniques

Provided by: unrealed.exe

Tomasz ‘Millennium’ Jachimczak

tomasz@planetunreal.com

Out Door Techniques

Many people want to create out door levels, and I have recently posted a few tute's about how to create them, but I have not really explained what you should keep in mind when you are actually creating them. It is a MUST to remember that you have to keep your levels as low in Poly's as you can. Let's face it. You might have a PII 450 with 256 Mb ram, and all the attachments that go with it, but not everyone has got that type of PC at home, and certainly not everyone playing Unreal has got a 3D Card to go with it either. If you wanted to follow the guidelines as set by Epic in Level design, you would never have more then 150 poly's in the players frame of view. Now I personally do go over that limit, bet certainly I try not to go too far over it. Let me use an little example here. I was doing a small village in a large outside area, and the village was visible from the outside, I first create the houses. I made them to look nice, but simple from the outside, and then spent a large amount of polygons on the insides of them so that when a player walked inside, they would feel like it was really a nice hut, but the outside of the house would not slow down the frame rate too much when a player saw the entire village from afar with a few houses there.

If you are doing large vast areas, and you want to have the next best thing to a plain there, why not create a fairly basic plain, and include a few little bumps here and there, but do not try to make the entire landscape bumpy and mottled. Doing that might look very nice, but if I was to try and play it on a smaller PC perhaps a P200 without MMX or 3D Card then I would think that it is a really hopeless level. It doesn't matter how nice it might look if it is unplayable for people.

Cut things off. If you can, include a few larger mountains or fences or anything like that that will help to break up the level. You can have as many polygons as you like - Just make sure that the player cannot see all of them at the same time. You can have a maze that has more poly's then a natural sphere but you simply have to limit how much the player will see at one time. Have a look at some of the inside levels in Unreal. You will find them to be quite detailed. There is a lot of intricate little things inside each room, and the entire levels are generally very full of cool little things to play with and gawk at. However now take a look at some of the outside levels, and see if you can find anything at all that will make the level slow down at all. The levels are almost bleak although due to the design of them, they still look great. If you remember the first outside level, the one with the nice falls and the outside of the spaceship etc, then you will see that the level is in fact very bleak, and simple on the outside, but as soon as you start going on the inside of the mines there, the geometry used suddenly gets a lot more complicated and "Eye Candy" intensive. This can be done as you will still have a much smaller limit of Poly's that you can see in the level at one time. The same thing with any level really. If you can hide all of the complex geometry to a smaller area where the player can only see a set limit of poly's at a time, then it will not hamper your levels playability and you can go to all sorts of lengths to create great eye candy and graphic feats.

This tutorial may seem like a lot of rambling really, and as I read over it, I am wondering if I should post it at all, but I guess that it will help some people out there, so it may as well go up :)


BB Drac - Unreal Tournament UED2 guide Brush Editing, Terrain Builder

Terrain builder

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Creating a realistic outside environment, with rolling hills and flowing lakes is not only very difficult
but also drastically resource demanding.
In plain words, a frame rate killer.

However, it is possible to do and as long as you stick to a minimum of details it could work out
pretty decent.

The best way to create 'realistic' outside environment is to use the terrain builder.
(Unless you are using external editing tools which I am not going to explain).

The terrain builder brush have its floor side divided into multiple polys and by moving
the vertices you can raise or lower the terrain.

It is a painstaking work but it will give you a lot of advantages instead of doing it with
other brushes.

This screen shot show you a simple 'hill' in a small area.
Screenshot

As you can see all polys / sides are triangular which allow you to move any vertex in
any direction without the poly / side being 'bent' or curved.

This is how a terrain builder brush could look when you first create it.
Screenshot

To modify a vertex it is best to mark the brush in the 3D view and then select a single point.
(In 2D view it is impossible to single out one vertex).

By holding down the ALT, both mouse button and then move the mouse up or down you either
rais or lower the point.

These two screen shots show you how it could look after you rais and lower the terrain.
Screenshot

Screenshot

When the vertex moving is complete you should make sure they are on the grid.
Both vertical and horizontal.
To make that easier you should create a terrain tool brush with a Width and Depth segments
in the power of 2.
Meaning that you should only enter 2, 4, 8, 16, 32, 64 or 128... and so on.
This will keep the points to the grid.

When you move them just move them up or down, but you will realize that they often
come out just a bit outside the current grid.
Simply move them back to the grid in the 2D views.

By doing this you reduce the chance of getting unwanted collision hulls and BSP holes.

When the builder is complete just subtract it and then apply any texture you want to the
surfaces.

If you want a lake just create a large zone portal and place it where you want the water-line
to be.

This builder brush requires some trial and error to get the grip on


BB Drac - BB Drac - Unreal Tournament UED2 guide The Outside area

Outside Areas

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

To create a level where players can move around with the feel
that they are outside is not that difficult.
What is difficult is to limit the players to a specific area and
still let them have the feel that they are outside.

To start off, the 'outside' is actually no other than a normal
room but all walls/polys is check as fake backdrops.
The outside look is then created with a skyzone.
(Check my skyzone tutorial on how to create one).

Now here comes the problem.
If you would play just this you could easily run to the end
of the room and bump into the invisible barrier.
The same will happen when you start shooting wildly into the
'air' and see that they simply hit something that is very close to you.

To create a feel of 'real' outside you need to create a very large room.
So when someone shoots rockets and like, it looks as if they
go far into the air and then simply go off without hitting something.

The problem now is that players are able to run far far far away
and in the end they still hit the invisible barrier.

There is a lot of ways to create the level and keep the players from
running outside the actual area.
Large walls and mountains might be it. Isolated island might also be a solution.
Take a look at a few levels and check how it has been done.
You will realize pretty fast that most of them create either island type
of levels or levels that is only partly outside.

Here is a picture on how the 'outside' could be done.
Screenshot

As you can see on the room to the left is pretty large and has the walls
as fake backdrops.
The small brush to the right is the skyzone.
In the middle of the large brush you can see what is supposed to be
the actual play area.
It has been limited with two walls and two sand dunes.

There is no rules or specific ways on how to create open outside levels.
Take a look on other levels and see how it has been done and try to create
something similar.

I will try to give you some information on different situations and
possible ways to create them in UED.

 Mountains:
A base or a crater in the mountains is maybe the easiest way of creating
the outside look.
The skybox is also pretty easy to create because the player would normally only
see the roof of it.

Imagine a courtyard of a castle and it is all surrounded by large mountain walls.
By creating a fairly wide and long skybox you can limit players view to
the roof of the skyzone only.
The castle could be built into the mountain to limit players to the front
and inside the castle, and allow you to build as far into the mountain as
you like.
(It doesn't need to be mountains, you can use city walls the same way).

Levels with this look: AS-Mazon, AS-Frigate, AS-Rook, DOM-Condemned

 Endless seas:
To create endless seas of water, lava, acid or anything that is supposed to
be used in the 'endless' look.
A horizon maybe?

This is could be pretty hard to do, depending on the theme/setting you want.
The problem is if you want daylight or night, and if players die instantly or
not if they are able to fall into this 'endless' body of water, lava or what it
is you create.

The skyzone will be more or less the same anyways, but a pretty wide and long
but not too high skybox will give you the feel of seeing the walls far off
into the horizon.
If you want a more 'round' and planet feel to the skyzone you might want to
create it cone-shaped. (It will however be more difficult to work with though).

If you want it to be night just make sure you avoid adding lights to the sides and
corners of the skyzone.
If you want daylight there might be problems.
Players will be able to see the sides and the 'outside' will suddenly look
weird.
A possible way to avoid that is to the let the walls be black and create
a star lit sky.

If players are able to 'fall' into the water, lava or what it should be
you need to think on how they should be able to get out.
If they die on impact all you need to do is to create a large zone portal
close to the 'bottom' and all falling down will simply result in death.
If they fall into water you might still want them to die but it takes longer time.
To do this you could create a zone portal close to the bottom and make it a warpzone.
players will be warped to another zone which is entirely filled with water and
drown.

Take a look at DM-KGalleon and CTF-LavaGiant, both use this type of look.

Levels with this look: DM-KGalleon, CTF-LavaGiant, DM-Barricade, DOM-MetalDream

 Worm holes / Moving levels:
For the fast looking walls you need to make them move, using U/V -pan and then
simply adjusting the speed.
What can turn out to be difficult is, if players should be able to fall
off and die.
If that is the case you need to zone specific areas and make them harmful.

Levels with this look: DM-Oblivion, AS-HiSpeed

 Asteroids and Islands in space:
This is maybe one of the easiest to create.

By creating a very large room all you then need to do is to build your island
in the middle of it.
When people fall off you need to have a zone portal and make a vacuum-zone.

Levels with this look: CTF-Face, DM-Phobos, DM-Morpheus


Making Terrain with TerrainED

By Matthew Walser

The Redeemer

Your ready for terrain, well, be prepare for the world of bsp errors. A bsp errors is like a hole in your world . in the Therefore, you good at making DM maps and pretty much get how to use the unreal editor. So you say game it produces a Hom effect (hall of mirrors). Which will get you a nice bad score at a reviewing site.
Here's pretty much what your going to learn

  • 1. how to make realistic terrain using martin "pfhoenix" actor's terrainED

  • 2. THE easiest way to use terrain edit

    First of (assuming you have downloaded and installed )start terrainED. There are basicly 2 ways to make realistic terrain in terrain edit , the easiest way is to randomly generate terrain using the "new random terrain " option in the "option" menu. Once you have a new terrain it should look like this .

    Now that you have a terrain it doesn't look like much. To view its properly go to the "window" option and select " all in one " once that's done its look the same but all in one . Hold the SHIFT key and left click the terrain and pull it closer to the screen. Release shift and click and hold the right mouse button move the terrain to the desired position now to change the hight of the randomly generated terrain . Click the terrain and press the left mouse button and the right mouse button simutainously and move its around until the desired appearance of the terrain appears . now to get that desired terrain into the unreal editor.

    First in the terrainED go to "file" and click "export" export the terrain as unreal text and only export the view range. Now save it as any old thing . Now open the unreal editor and start a new map. Now make a cube about 1024x1024 with any textures. Now the tricky part to export the brush. click the bush menu and Click import now select the brush that you exported for terrainED once in the when the importoptions menu comes up click "contains gaps or holes" when imported it should appear likethis.....

    When like this you can add subtract or do what ever to it. Now for the second way to make terrain in terrainED. You will still have to remember all the exporting and importing mumbo jumbo. First off you open any quality image making program and make a black back grounded picture And draw on it , with white and shade of gray, white is the highest and black is the lowest . Draw something like this .

    When your done making the picture open terrainED once again and go to the "import" option under the "file" menu and import your picture /once imported it should show up on the view. Then you just export it to and .t3d file (unrealtext) and open it in the unreal editor.


Unreal Editor Maximum [unrealism.com/unrealedmax] -Vertex Editing And Terrain Builder

VERTEX EDITING AND TERRAIN BUILDER (OUTDOOR LANDSCAPES)

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This tutorial is aimed at the intermediate level designer and will show you how to make use of the vertex editing feature to manipulate brushes and how to create realistic looking outdoor environments using the Terrain Builder (some of you familiar with vertex editing may want to jump to the terrain builder part).

BASIC VERTEX EDITING

Vertex editing helps you to manipulate the edges or vertices of brushes. The brush can be of any type - a solid, semi-solid, an added brush, a subtracted brush, etc. [Newbie mappers may want to have a peek at the Semisolid Tutorial]. Vertex editing basically helps you to move the edge of the brush in virtually any direction that you please. I'll show you how to move the vertex of a simple brush.

REMEMBER: Basic vertex editing here refers to moving a single vertex one at a time. Complex vertex editing refers to moving multiple vertices at a time (discussed later on in the tutorial).

STEPS INVOLVED

  1. First and foremost lets make the two rooms for the level. The aim is to move a few vertices of the first room onto the second room. Make the two rooms 512x512x512 in dimension. Ensure Vertex Snap is turned on. Set gird to 16 units (important to follow my steps latter turn it to this).

  2. IMPORTANT STEP: Remember a cube brush has 8 edges (vertices). In this example we are concerned with only 4 of them. It would be more convenient to name the four vertices of the first room like this:

    Remember that in the top down view you will only be able to view vertices A and C. This is how they look:

    To see vertices B and D look in the front and side view for each one.

  3. Selecting A Vertex: Ok now we need to select vertex A before we can move it. First select the brush so that it is highlighted in all the views. Now hold down the right mouse button and click on vertex A in the top or side view. When you have selected a vertex it is highlighted with a red dot like in the picture on the top.

    Now it is important that you verify that vertex A is the one that is really selected by going to the 3d view and having a look. if it is not hold down the right mouse button and click on vertex A in the 3d view itself.

  4. Moving A Single Selected Vertex: This is the crux of the matter. Now that vertex A is selected, here is the vertex editing commandment:
    HOLD DOWN ALT AND THE LEFT MOUSE BUTTON AND DRAG VERTEX IN DESIRED DIRECTION
    In our example drag vertex A in the top down view to the following location:

    Now select Vertex B in the top down view (it should be easily selectable now that vertex a is out of the way). Now move it to the same location as vertex A in the top down view (hold down ALT and left mouse). See this in the top view:

    Now all that is left is to do the same thing to vertices C and D. Now select C (it could even be D), hold down alt and the left mouse button and move it. Then select D and move it to the same position as C. The final top down view of the vertex edited room One is shown below:

    You should now see the first room connected to the second room in the 3d view.

  5. WARNING - Editor Crash Ahead: Ok everyone get out your crash helmets ;). The current version of UnrealEd 2.0 does not support dragging of vertices on top of other vertices on the same brush (will be supported in a future version I don't know when) - the editor will crash on you. Now save all your work and TRY THIS OUT ON AN EMPTY NEW LEVEL (I will not be responsible if U screw your level while trying this). Why am I asking you to crash the editor on purpose?. Well this will just clarify the point to you and will drive home how not to make INVALID VERTICES. Drag vertices one on top of the other to see the limit.

  6. VERTEX SNAP (TO GIRD): This button [image] which is located at the bottom of the editor toggles vertex snap on and off. When this is turned, and you drag a vertex say A it "sticks" to the gird (depending on the amount of the gird value it moves from one point ton the gird to another). When it is toggled off you are able to move the vertex independent of the gird. Try this - turn the gird way down to 1 unit, toggle of vertex snap you now see that you will be able to move the red vertex dot off the gird to any place on the 2d view that you like. Another great use of the Vertex Snap (toggled on state) is that it allows you to align brushes to the gird with a simple click. Say the red builder brush is not sitting on the exact lines of the gird, just select it and right click on any of the vertices - it will automatically jump to the gird (naturally if its already on the gird it wont "snap" :). You will be using this feature a lot in your level building process.
    NOTE: There are two other buttons near the vertex slap button. The one of the gird when toggled off allows you to move a brush without it sticking to the gird and the same thing applies to the circular button (it allows free rotation).

  7. REBUILD TO SEE THE EFFECT: In order to see any of the changes in the 3d view you must immediately rebuild the level. Its a good idea to rebuild the level constantly to see what effects vertex editing has wrought on your masterpiece.

  8. MISC TIPS: Sometimes the brushes vertex may misbehave and if this happens for some reason just right click on the brush go to the reset submenu and choose reset pivot. Now try selecting the vertex again. HOT TIP: If the brush does not snap to the gird properly - first turn off vertex snap, select the vertex and then turn on vertex snap and move the vertex (this has proved invaluable in a lot of cases.

MULTIPLE VERTEX EDITING

Warning!!. It is important that before proceeding with this part of the tutorial you are familiar with and have understood how simple vertex editing described above works. Whereas in the previous example you moved only one vertex at one point of time, multiple vertex editing allows you to do just that - move multiple vertices at the same time. The concept of multiple vertex editing is relatively simple. I'd like to kill two birds with one stone. I'll explain how to move many vertices simultaneously and how to create realistic looking terrain with UnrealEditor 2.0 itself.

The Terrain Builder Button

This button is called the Terrain builder (located in the primitives section) and allows you to create BSP based terrain. Even though there are custom programs like TerraEdit that allows you to make great outdoor levels it creates a lot of BSP holes and needs a lot of manipulation to make the level run fast. Whereas the Terrain Builder allows for greater control over the terrain. You can make the terrain using multiple or simple vertex editing. Lets see how to use multiple vertex editing to create terrain using this brush.

  1. Make The Brush: First open up the Terrain builders properties, and put in the following values or the values that you need:

    The width and depth segments determine how may vertices that you actually have to edit. For this example I used width segments =5 and depth segments =5. This gives you a comfortable amount of vertices to edit, while at the same time it doesn't overwhelm you. The actually terrain that you will be able to create depends for a large part on these values. Ok now enter these values and subtract the brush lest see how to create realistic looking ground with this brush.

  2. ENABLING MULTIPLE VERTEX EDITING: Well then, lets get into vertex editing mode, hit this button: . If at any time you want to go out of vertex editing mode you need to hit this button [image]. It will immediately take you out of vertex editing mode. Now that you have enabled vertex editing mode. Go into any of the views (for now try the top down view its more convenient) and left click on the subtracted brush. The whole view changes like this:

    It is IMPORTANT that YOU SELECT A BRUSH before editing its vertices or you will not be able to perform any action on it.

  3. SELECTING MULTIPLE VERTICES: You can select multiple vertices by holding down CTRL and left clicking on any of the vertices. But by far the best method is the CTRL+ALT+DRAG method. This method works in the following way - hold down CTRL+ALT and the left mouse button while the cursor is pointed at any of the 2d views and drag the mouse cursor over the area that holds the vertices that you want to select. Now try this in the top view over say four vertices of the brush in the center (select the brush first if its not already selected).

    After the CTRL+ALT+DRAG over the area that hold the vertices that you want to edit, on releasing the cursor you will see all the vertices within the red box selected (highlighted in white) like this:

    That's how you should select multiple vertices all the time.

  4. MOVING MULTIPLE VERTICES: Well now that you have the multiple vertices that you want to move selected, HOLD DOWN CTRL+LEFT MOUSE BUTTON and move the vertices in the desired direction in any of the 2d view ports, thus:

  5. MOVING VERTICES IN THE 3D-VIEW: You can move the vertices that you have selected directly in the 3d view. To do so select the brush and select the vertices you want to move (remember that you can select a brush in the 3d view by holding down SHIFT and left clicking on any surface of the brush that you want to select). After selecting a single or multiple vertex hold down CTRL and the left mouse button to move the vertices forward and backward. To raise and lower the vertices hold down CTRL+LEFT MOUSE+RIGHT MOUSE BUTTON and move the mouse up or down to raise or lower the vertex and left and right to move it in that direction.

  6. Now that you know how to use multiple vertex editing, its time to experiment a little to see what you can come up with. Select a few vertices at a time and move them up or down to create hills and valleys respectively. See what you can come up with:
    Click to see larger picture.
    (Click to see bigger picture). I was able to get a frame rate of 80 fps in this scene - I doubt that if I had used TerraEdit I would have been able to create terrain like this. Not only that the scene looks great as well. Even though the terrain builder may involve you having to move vertices one at a time the effort that you put in is worth it to get some great scenes.

TESSELLATED CUBE

The tessellated cube allows you to create realistic looking stuff like rocks via multiple vertex editing described above. Making use of this feature is as simple as turning tessellated to true in the primitive cube properties:

Lighting outdoor terrain can be a big pain - but its better to use a small number of lights with a large radius. Also creating a realistic looking (and interesting ;) skybox is a difficult job. If you are still a novice you can brush up on your skills with the Lighting Tutorial and the SkyBox Tutorial. That concludes the vertex editing and terrain tutorial. If you need more information please email me. See u in the next round!.


Outdoor

Outdoor / Natural looking sections

By: ]V[ATTerminator Matterminator@planetunreal.com

http://www.planetunreal.com/matterminator/

Tutorial:

Creating good looking outdoor sections to your levels isn't as hard as a lot of other tutorials make it out to be. I've seen a few tutorials that suggest you keep turning a cube, cutting off pieces up against another brush. That can take ages, is prone to BSP errors, and can make poly counts extremely high. Take a look at the cliff face that separates the two bases in CTF-LavaGiant. That's only about 10 polys each side, and still looks fine. Here's a few ways of adding a good looking natural section.

Usually, I start with a cube, about 20% bigger than the size I want the room to end up as. I then make a section of natural looking terrain with the terrain tool.

To make a terrain section like this ( pic below), click the terrain tool (two buttons down from the sphere). Set up how big you want it to be. In this example, make it big enough to cover the largest side of your cube. Then use the vertex editing tool to drag around the vertexes, until it looks a little like the pic below. To use the tool, drag a box around the vertex using CTRL-ALT, and hold CTRL to drag it round.

When you're happy with your terrain section move it so it covers part of your room ( pic below).

Then deintersect it, and add it. Repeat this with the other sides of your cube. It should end up looking a little like the pic below.

The pic above took next to no time to make, and isn't too bad. The lighting on the pic is poor though. Lighting with these sort of levels is paramount. Lighting can bring out the parts you want. Ambient lighting helps a bit, don't rely on it.


Creating Realistic Outdoor Scenes

By : Matt Murphy

utcity@planetunreal.com

UT City

FOREWORD:

Ever wonder how Epic can make those walls, cliffs, terrain, and just about everything else outside look so real? Well after a little experimentation I've found a way that really works. Basically what I did was I created a grayscale image, then imported it into Terra Edit using that I imported into UnrealED. Right now I'll show you how to do this, but first you will need UnrealED of course, Terra Edit, and a paint program. I will be explaining on how to make the grayscale images using Adobe Photoshop but this is possible in Paint Shop Pro. I just find it easier in Adobe Photoshop. Ok, now onto the tutorial.

DIRECTIONS:

Part 1: Creating the Grayscale

First open up Adobe Photoshop, or whatever paint program your using, and create a new image that is 512x512 and that has a black background. Next set the Red, Green, and Blue values to 64, 64, and 64 for the foreground color. To do this using Adobe Photoshop look below:

You should end up with a gray color. Ok the next part is freehand so select either the [image] Paintbrush tool, or the [image] Airbrush tool. Now, in the same little box where you selected your color, click on the brush tab and select the little box that has a circle in it with the number 45 as in below:

Now on your image start painting some random lines or create a little scene. Note: The lighter the gray color is the higher in elevation it will be in UnrealED so black is sea level and white is mega high or something (never used white before). Anyways when you have something similiar to below you can continue.

Now change your foreground color again to the following values: R-16, G-16, and B-16 (Red 16, Green 16, and Blue 16), and also change your brush size smaller to about 35. Now you'll notice that you have a darker gray color. This will be terrain just above sea level while the black color will be at sea level. Now again draw on your image but this time in between the lines like so:

Now expand the image and use the [image] Selection tool and select the entire image. Then create a new image that is 256 by 256 and has a white or colored background. Now paste your previous image onto the new image. Then go to the Edit menu, down to Transform, and select on Scale. Then resize the image to 256 by 256. Now again maximize your new image and use the [image] Selection tool and select the entire image. Create yet another new image that is 256 x 256 but this time make it a grayscale image. See below for illustration.

Copy the old image onto your new image. Now go to the file menu and select Save a Copy. Save it as a .BMP file. Then select the following properties and click on Ok.

Part 2: Importing it into TerraEdit

Now go ahead and close Photoshop if you want and open up TerraEdit. Go to the file menu and select Import. Then open your file and you should see a small little box appear asking you for a grid scale and size. Set it to the following: Grid Scale:64;Grid Size:32x32. See below for illustration:

Then press ok and you should see your terrain appear. This is how the one I made turned out:

Now if you wanted to make any revisions either go back and modify that grayscale or create a new one or you can modify it in TerraEdit. Use the directional keys to move the red arrow around. Press the Enter key to move the point a unit up and press the Shift key to move a unit down. You can also smoothen out your terrain easily by going to the Tools menu, then into Filter, and select Smooth. Then go to the File menu and choose Export. Save it as anything you want but just remember where you saved it. And make sure you chose Export and not Save!

Part 3: Importing it into UnrealED

Now go ahead and close TerraEdit and open up UnrealED. Now create a cube that is 8192 x 8192 x 8192. Next open up the GenEarth.utx texture file and find the texture called 'Dirt1'. Click on that texture and add the cube into the world. Now go to the Brush menu and select Import. Now find the file you saved from TerraEdit and click Ok. You should then see a box with some options on it. Click on the following ones.

When using UnrealED 1.0 | When using UnrealED 2.0

Now you'll notice that the brush is only 1/8 the size of the cube in area. This can be fixed. Right click on the brush and go into its properties box. Then click on the plus sign next to the word Brush, then go into MainScale, then Scale, and set the X, Y, and Z values all to 4. See below for illustration.

Now align the brush to the bottom of the cube and so that all four sides of the brush are inline with all four sides of the cubes. Once aligned correctly select the texture called 'MGrass7' from the GenEarth.utx group and subtract the brush. Excellent, now you've got your outdoor floors. Use the camera to take a look around your terrain. From there you can add lighting, trees, bases, bushes, water/lava, or just about anything to make it look more realistic. I will be explaining these in a later tutorial so for now you are on your own, but I don't think its to hard to figure out. To make realistic walls, all you need to do is a a very light gray, almost white color to the outside perimeter of your grayscale and it will be as if you are in a valley. Below are some examples of grayscales.

CONCLUSION:

Now you should know the basics of creating realistic outdoor landscapes. Future tutorials will include such things as rocks, river systems, cliffs, lighting, and more. Realistic mapping takes time to master so don't expect to be an expert at it soon. This tutorial is just made to point you in the right path.

OTHER:

-=[Copyright/Permissions]=-

Questions/Comments email me at Murphy149h@mediaone.net .

This tutorial is Copyright (c) 2000 Matt Murphy.

This tutorial is not supported by Legend Entertainment or Epic Games.


Making Advanced Outdoor Terrain while keeping your Poly-count LOW!

Tutorial:

I'm sure you have all played the map CTF-Conquest by the legendary Chris "Plutonic", gazed at it's beauty and then wondered how he got such amazing looking terrain. Well now you don't have to think or look no further, cause I have a way of doing it too and I'm going to share my technique of making terrain with you all while keeping the poly count lower than 30!

My technique is about 50 times better than using the "Floor Lofter" and even better than using terra edit. You can get the results you need at a fraction of the Poly count.

But wait, There's more.............no there's not, here's how it's done!

Using the 2d Shape Editor make a 2d shape that would look like a valley from a birds eye view. Make it huge!. While using the 2d editor for this Tutorial DO NOT move the green curser as it will f**k everything up.

(The picture below has been zoomed out twice. This should give you an Idea on how big to make it)

After this Simple task, save the 2d shape so you can load it back up later. (This is Necessary!)

Extrude the shape with a depth of 768 and Subract it from your world. Open up the texture pack "Genearth.utx" and make the walls of your subtracted brush "Rock 7" texture and of a scale 4. Set you roof to "Fake Backdrop" and leave the floor how it is.

Now. Open up your 2d Editor and load the 2d shape you just made. You will notice it is made up of a number of triangles. Delete all but one of those triangles and you will get something looking like this. The picture below is the top triangle of the shape I made above.

Having the one triangle left and without moving the green curser, extrude the triangle with a height of 128 and place it in align with the subtracted brush like shown in the picture below.

Once this is done you need to do some vertex minipulation. This is one of the hardest to do thing with Unreal editor because when not done properly it will cause all sorts of nasty errors.

First turn on the "Grid" and turn on the "Vertex Snap" button. With this on the vertex's you move around will automatically join to another. With this done, by holding alt, move the upper middle vertex up a couple of units. (Avoid going higher than 8) NOTE: When moving vertex's up and down, make sure they are perfectly horizontally aligned in the "Top View", if this is not done correctly it will result in HOM and BSP cuts and holes.

Once the Vertex has been successfully moved vertically, it should look like this:

Once this has been acomplished, hit the "Add" button and add it to your world with the ground texture of your choice. Now open up the 2d Shape editor and load up the shape again. Delete all the triangles bar the one that connects to the one you just used.

(Confused????? Check the pic!)

After deleting them all, extrude it with 128 depth. Because you are using the same shape as you did with the last one, the triangle should line up perfectly with the previous one. (As long as you haven't moved the green curser, this will move it a few units left or right).

Now, the two top vertex's of the "Active brush" should be touching the two top ones of the added brush. (See pic below)

Beautiful, it's lined up.............but it's flat.....flats not real!!!! Lets make it real!

After doing this, you will have something looking a little like this! (I moved the vertex done in this case!)

Now, open up the 2d shape editor and delete all the triangles bar the necessary one (The one that touches the one you just used) and extrude to 128 depth. Now, you will notice that one of your vertex's do not line up with the Poly you last added, simply make the corrections by lowering or raising your vertex to the point where it "Latches" on to the right place. (it will only latch on to another vertex if "Vertex Snap on" is set). Now that every thing is lined up it should look like this.

. . . . . .. . . . . . . . . . . . . . . . . . . . . .

See how it's all nicely lined up? Does it look real?? if not, just move the spare vertex up or down until it looks right!

After lining it up so it looks nice, "ADD" it, and go on to the next triangle, then the next......and then the next until you've done all 6 of them. Then go onto the texturing. When texturing avoid changing the scale to anything higher than 3 times bigger, it tends to look shitty. Use a variety of different shades and tones to make your outdoor area look nice. Then, once this is done, select all the surfaces and set them to "Bright Corners" under the effects, this will make it un shadowy and natural looking!

And the end result......

Only 100 Polys

Only 32 Polys!

Or this Beauty, only 113 Polys

Conclusion: So now you now how to make awesome looking, outdoor scenes. . . so get to it! be creative!

FINAL TIPS: Use alot of decorations in your outdoor scenes. Mainly the trees and plants. If you think the plants are to small, make them bigger!

Also, remember use the most realistic textures you can find, the best packages for this are "Genearth.utx" and "Genterra.utx". Also always have some water. makes everything look so much more natural. Get the lighting nice and the sounds going good to. And to make it even more spectacular, have a beautiful, no more than 15 polygonal moving skybox!

And finally, always check your polycount, remember, you want to keep the Polygons under 150 and the Nodes under 350. Have Fun!


How to make a Waterfall

By: John "Deadbolt" Milam

Forward:

The question of how to make a waterfall came up in the UT newbie guild’s forum. And I was the first to step forward and try to tell some one how to build one. Then some how I was given charge over making a tutorial, to honestly tell you the truth I’ve never made a water fall in any of my levels before. But I have a pretty good idea how to do it, so I spend 3 hours of off and on work and I made a small little level that has nothing but a water fall a pool and a player start. Any way on to our show.

Assumptions:

I hope that you have a level design worked out. Depending on your map setting the Waterfall could originate from anywhere. But since most waterfalls come from rocky places. Here goes…

(Another note if you have level with a Waterfall and then waterfall comes from a rocky area that is square and flat: hit your self upside your head. Flat cliff sides look like your not even trying, because rock formations are typically jagged. It is far better to take advantage of brushes that look like rock formations, will give a better sense of place)

Note that in my example that I have a pool (where water can flow to) and crevasse area near the top of the cliffs as a source of the waterfall.

Now this is where things get tricky. If you have a waterfall that is up against the wall and plays no important part of the level other that decoration, I recommend just using a sheet brush. However if you want to be able to stand in the water you need to use a brush that has some thickness. (See below, I have to be complicated)

(Now you’ll notice in my example that the bottom of my waterfall becomes narrow at the bottom I did that in part because of the direction the water comes from. And I’ll add other brushes there later.)

When placing the brush for either type of waterfall use the Add Special tool: this tool as several preset settings use the Water one. Now if your waterfall set up so you can stand under it, you will also want to check the 2-sided attribute. That means it will also act like a separate zone, and when you stand inside you can see the sides of the brush. Brushes that are not 2-sided disappear when if you "enter" them. Also That way you can set zone info in it if you want. Also if you where to stand in the waterfall you would still be able to see the brush itself. When you set the brush you’ll want to also leave it just a little off the cliff wall when you stand under it you will see all sides of the waterfall.

Also you’ll want to set the Waterfall’s surface properties so that it pans downwards.

At this point, the waterfall’s texture doesn’t look right? It is the same texture as the pool and it flows down but it doesn’t look like it is a waterfall. In the surface properties select the Alignment tab, and under scaling there is a U property and a V property. Change this accordingly setting one of the scaling markers at 1 and the other to a number between 5 and 15, these number can change depended on how large your waterfall is.

(Ok that’s better)

But here the next problem when fast moving water hit’s still water there is a mist and wave effect. Thus the question

Is how to do this? You can do it one of two ways either by using sheet textures or actor effects. For and example of the sheet texture look at DM-Arcane Temple:

At a distance the mist effect looks good. But up close it losses it’s appeal.

Also there is a wave texture put in to further the illusion.

Now lets look at the other method and the one I used. In the Actors browser there is a category called: Effects.

And in effects there is an actor called Short Smoke Generator that produces a sprite effect that looks 3D.

oooowww, mist

As for the smoke generator is the settings whish you should try and play with so that they suit your levels needs. There is one setting called "TotalNumPuffs" that sets how many smoke puff that this actor produces. Either way you will have to set a trigger connected to each smoke generator, because when the "puffs" run out a trigger will set off the smoke generator again. You should do this just in case that number runs out (even if you set it at a ridiculously high "TotalNumPuffs", place the trigger in an area of player high traffic.

Also if the waterfall doesn’t match the rest of the pond don’t worry the right lighting can fix that.

Don’t set the smoke puff at too large of a size or they will look blocky

Keep in mind the placement of the smoke generators, too many, too close together and it won’t look right.

Look at the waterfall from all angles

With trial and error you’ll find the right arrangement. Now I’m compelled to finish this as a level

Ok that’s my tutorial, don’t forget to add Ambient Sounds you’ll find some good ones of waterfalls in AmbOutside.uax

Good luck.


3DS Max Terrain For UEd2

Enviornment Maps in UT

By: Adam ‘Muad'dib’ Stiles

http://www.planetunreal.com/muad

muad@planetunreal.com

PRE-REQUISITES:
A basic knowledge of UnrealEd
An Q2 or Q2-like env map (try one from my env maps section)

Today I show you how to use all those env maps that I have for download in the env maps section.

So just what the heck is an env map? It's short for "environment" map and is basically a set of 6 square images when mapped onto the inside of a cube, form a panoramic view of an environment. Think of it as standing inside a perfect cube shaped box - now take one image out of the set and plaster it onto a wall on the inside of this cube. Keep doing this for each wall (ceiling and floor included) such that the images tile from side to side, top to bottom. Env maps are the choice of sky implementations in the Quake 2 engine, so you might have seen quite a lot around the internet, well, today I'm going to show you how to adapt them to use as skyboxes in Unreal Tournament.

First things first. You're going to need an env map that's been made for Quake 2. I've got several for download myself, but you may also choose to use someone elses Quake 2 / Half-Life env maps. Note that in my downloads I've included a bunch of TGA files. They are in that format for a particular reason - TGA will support millions of colors with a slight compression ratio. This way you can *alter* (remember to still give me credit if you decide to alter use my env maps) the env maps in your favorite photo editing software without loss of quality. Not to mention Quake 2 env maps, by default, are in TGA format (at least those are the ones we are going to use) and I want you to get the WHOLE process here for learning purposes. Now let's get to it!

You should have an env map by now. Whether or not you got one of mine or someone elses, put all the TGA files (6 of 'em) into a directory of their own (for neatness' sake). Open up your editing software (I'm going to assume Photoshop, but this can also be done in Paint Shop Pro which you can download a trial of at http://www.jasc.com) and load all 6 of those TGA files up. Now, UnrealEd doesn't like TGA files - it likes BMP files. So we're going to have to do some converting. So in Photoshop with your TGA files open:

Goto Image->Mode->Indexed_Color with these settings:
Palette = Adaptive
Colors = 256
Forced = Black and White (this selection is for Photoshop 5.5)

You'll probably want a diffused dither as well, doesn't make a LOT of difference - the above settings are the important ones.

After you've done that, save the image in the same directory with the same name, but as a bitmap file (BMP extension). Do this for ALL 6 images.

Now you should have 6 BMP files, each one 256 colors. You're ready to fire up UnrealEd now, so go ahead and do that.

Now, our env map is going to work just like a regular sky box in Unreal which means we need those BMP files as separate textures in UnrealEd, so select the Texture browser. Click on the "Import" button at the very bottom of the Texture browser. Then find all those BMP files you just made and highlight all 6 of 'em. Then click the "Open" button and you'll be prompted for some information:

Name = This is the name of the image, just leave it at the default
Group = You can leave this at the default as well
Package = This is important. Type a name here that you want the env map to be known by - this will also be the name of the texture file (UTX) that you save as. For this demonstration we'll use "ENVMAP1" (no quotes), but could just as easily have used something else.

Make sure the "Generate Mipmaps" option is checked and then click the "Ok to All" button.

UnrealEd will start working for a moment and when it's done you should see all 6 of your env map images in your Texture browser ready to use. Now let's make a skybox to use them on!

First right click on the cube brush tool button: and goto "Cube Properties". Make sure you have the height, width, and breadth set to 256. NOTE: You can use wall sizes of any size really, multiples of 256 are best, it just means you'll have to resize the textures later and we wanna keep this simple.

After setting the size dimensions, click the "Build" button and you should have a 256 cubic brush in your view now. Go ahead and close the Cube Brush dialog.

Now select a DIFFERENT texture - something that clashes with your env map (I know, just stick with me here). You want to be able to easily distinguish the map from the texture. Now on your Texture browser you should notice three drop down menus. The first is to choose what kind of things to browse (Classes, Sounds, but in this case Textures). The second is the differnt Texture packages you can browse within. The third is usually categories for the chosen texture package. From the SECOND drop down, select "Engine". Then click on the green-scaley looking texture called "DefaultTexture" - good name for it huh?

Now click the Subtract Brush button: to create your basic skybox. You should have a cube with that scaley texture all over it. Now go back and select "ENVMAP1" from that second drop down list.

Now the fun part, we're going to map the skybox. These instructions are important. You'll notice that (if you used a Quake 2 or one of my env maps) the names of the textures will end with "bk", "ft", "lf", rt", "up", or "dn" These tell you what walls for the Quake2 engine to put the texture on. They'll also be our markers for putting the right textures on the right walls.

Here we go:

In the 3D view, face a wall (not ceiling or floor) - highlight it (by clicking on it in 3D view) and put the texture ending in "ft" on it. Now in 3D view turn to the right to face the immediately adjacent wall.

On this wall place the texture ending in "rt". Turn right again to the next immediately adjacent wall.

On this third wall put the texture ending in "bk". Turn right once more to the last wall (minus ceiling and floor which we'll do in a second here).

On the fourth wall put the texture ending in "lf".

Now, put the texture ending in "up" on the ceiling, and the texture ending in "dn" on the floor. Don't worry if they don't look like they line up right. We'll fix it soon.

You should now have a skybox with all 6 of your textures used. Now, odds are that you have a problem: The ceiling and the floor don't "mesh" with the rest of the textures seamlessly. Well, they WILL. We just need to rotate those two textures to fit right.

First click on the ceiling in 3D view to highlight it - then right click on the ceiling in 3D view and goto "Surface Properties" Under Surface Properties, click the "Rotate" tab. Click the "+90" button until the ceiling lines up seamlessly with the walls.

Repeat this same procedure for the floor.

You should now have a nice looking skybox! NOW - there have been some cases, from my own experience, that importing these textures like this and placing the textures on the walls winds up producing light colored "lines" along the seams. That is you can see that the images line up correctly, but there are visible seam lines on the edges of the cube. IF you experience this, then follow the directions below. Otherwise you can skip to the "SKYZONING" section below.

FIXING THE LINES:

To fix those lines, we're going to trick UnrealEd a bit. Highlight any wall of the skybox in 3D view and press SHIFT-B to highlight all the sides, top and bottom. Right click on any of the sides and goto "Surface Properties (6 Selected)".

What seems to cause the problem is texture size for some reason - I think sometimes the texture comes out smaller than needed so it wraps around causing those visible "lines". So to get rid of them we're going to scale the texture size up by a very small amount to get rid of the wrapping around. Click on the "Scale" tab and enter the value "1.01" into the number entry box under "Simple Scaling" - then click the apply button. If all goes well, your 3D view should show that the lines are gone. You may also have to adjust the position of the WALL textures only by using the "Pan" tab, then adjusting the position with the pan buttons.

SKYZONING:

Now that the textures are on your sky box and you're sure they work well - you're going to want to save them into a package that you can then distribute with your map. After all, not everyone is going to have your new textures and they'll need 'em to get your sky box working right! So in your Texture browser make sure you have "ENVMAP1" selected in the second drop down box, and then click the "Save" button at the bottom of the browser. It should pop up a dialog wanting to save it as "ENVMAP1" in your UnrealTournament\Textures directory with a UTX extension. Go ahead and click "Save" to save the package. It's important that you include this UTX file with your map when you distribute it. And make sure that the people playing your map put this UTX file in their UnrealTournament\Textures directory before attempting to play your map. Otherwise it just ain't gonna work.

Unreal uses sky boxes differently than Quake2 does. Our env map was designed for Quake 2, so we'll need some more adjusting of things to make it look correct in Unreal. Every sky zone requires a "SkyZoneInfo" actor inside it somewhere. You can find it by browsing "Classes" (top drop down list in the before mentioned 3 drop down lists). Then expand "Info", then expand the subclass "ZoneInfo" - there you'll find a "SkyZoneInfo" class. Being a subclass of "ZoneInfo", a "SkyZoneInfo" can do pretty much the things a ZoneInfo can. However, it's a *special* ZoneInfo that says "Hey, this area I'm inside of is intended to be a sky!" So highlight "SkyZoneInfo", then right-click on your grid (inside your skybox) and choose "Place SkyZoneInfo here". Now position the thing so that's it's DEAD CENTER in the sky box from all views. There's a paramter you need to set on this thing now. Our env map looks kinda the way we want it already. We don't want any extra lighting effects, so right-click the SkyZoneInfo and goto "SkyZoneInfo Properties".

Under the SkyZoneInfo's properties expand ZoneLight and set the AmbientBrightness = 255.

That should do it! Now just build yourself a typical level there that you'd like to use your new skybox with, and set the ceiling's "Surface Properties" to have "FakeBackdrop" checked. That will tell Unreal to draw your sky on that surface instead of the regular texture. Then fire up UT and admire your new sky!

Have fun and enjoy converting all those Quake 2 env maps you used to like! :)


2D Editor Basics

    Chris Willis
    chris.willis@sierra.com

    1. Once in UnrealED pull down the "Window Tab" and go to the " 2D editor "

    2. After you've opened it you will see a blue triangle, each side of the triangle can be edited by pulling on the corners of the triangle or by inserting a vertex under the " Vertex Tab ". Each vertex inserted can be moved to make the shape more interesting. Remember: When you use this tutorial think of the object as one half of the whole object you want to make because you will be revolving it, not lofting it. The shape being made will rotate around the green crosshair so the crosshair needs to be at what will be the imaginary center of the finished shape ( the green crosshair needs to be on the left-hand side of the object, ok? ). :)

    3. Go to the "Loft Tab " then to " Revolver ". There you'll be able to choose how many sides you want your shape to have. I used the default of " 6 ".

    4. Hit Build ,and there you go! Your custom shape is made.


Wolf's Tutorial 2D Shape Editor

Wolf's Tutorials: The 2D Shape Editor

By : Tony 'Wolf' Garcia Tony Garcia

Wolf's Unreal

Introduction

This tutorial is the third in a series by Wolf to help people with the more advanced features of UnrealEd. If you are new to UnrealEd then please go back and read a basic tutorial, and then Wolf's 1st and 2nd tutorials to get up to speed. If you are a seasoned UnrealEd user and are just not familiar with the 2D editor this will be easy for you!

Part One - 2D Shape Editor

You find the 2D shape editor on the menu bar at the top under Window. The fourth item down. Before you jump right in and get lost let me give you some info. First off, this tutorial is by no means the end-all of 2D Editor usage. In fact, it will be pretty basic. For a little more complete tutorial on the subject you should read the article on UNREALIZED by Myscha the Sled Dog. This tutorial will refer to that article from time to time, but even if you haven't read it you should be able to follow along.

Now, the 2D editor is labeled as "Experimental" and the reason is obvious: Bugs. It can crash if you don't treat it right. It is not perfect. And though it is absolutely powerful, it has it's limits. First of all it is basically a vertex manipulator you use to make a basic 2D shape and then "extrude" or "loft" it to a 3D shape. If you have used any 3D modeling programs (such as 3DSMax or Lightwave) you should be familiar with this concept. If not you can understand it in terms of UnrealEd by being able to make a sheet brush (but with many more than four sides) and stretching it upwards to make a 3D shape out of it.

Second, do not cross vertices in the 2D shape editor. It will give you a very strange looking brush and will do weird things when you add/subtract it. What the editor actually does is shapes your red brush (the builder) and then you can use it to make these complex shapes. Like I said, I am not going to go into all the things this editor can do, but cover a few important ones you should know about.

When using the 2D shape editor BACK UP OFTEN. Do not minimize the editor while the 2D shape editor is open, though you can (and often have to) resize the 2D editor window. Do not attempt to Undo with it or delete any vertices you add. This will only cause the editor to crash. If you mess up simply close the window and start again. I know, that's a pain if you are in the middle of a fairly complex shape, but this is experimental and limited. So you are warned!

Getting Started

Now you know where to find the 2D Shape Editor, let's see how it works. Open the 2D Editor and you should have a black screen with a blue grid and a big green triangle in the center. That triangle is your starting shape. We can add vertices to it and move the existing vertices around to get the shapes we want. I hope you know that a vertex is a point, the angle where to lines meet. To move a vertex in 2D editor is easy. simply click and drag. A little circle will appear around it when you do. Click a vertex and move it around a bit. see how it resizes the triangle when you move it? Okay, see the cross in the center there? That is your center point of your shape. For the first part of this tutorial it is not all that critical but later you will see why it is important to have it there.

Let's start with something easy. The first thing you will want to do is add a vertex. If you click any vertex of the triangle you can see how it highlights a "leg" or "arm" of the triangle. Click the top vertex and it should highlight the right leg. now click it again and it highlights the left one. This is how you select which leg you are working with. If you have a vertex with multiple lines coming out of it (and you will) just keep clicking that vertex until the arm you want is highlighted. When we add a vertex it will be added to the middle of this highlighted line. Okay, let's learn how to add a vertex. Go ahead and highlight the right arm of the triangle. The easy way to add a vertex now is to press CTRL-I (for insert) but you can also do it from the menu at the top under Vertex-then Insert. Now you should have a new line in the center of the triangle from the lower left corner to the middle of the right arm. You have just inserted a new vertex on the right arm and split that line in half. Click where the new line meets the right arm and you should get your little circle. You can now move this vertex around like all the others. You can see how we can make various shapes with vertex insertion. But remember: Do Not Cross Vertices. Do not drag a line over and existing line. About the Grid. The grid is set to 16 units. This translates to 16 units on your map as well, so you are editing in scale. If you make something 64 (4 grid boxes) units wide in the 2D editor it will be 64 units wide in your map.

Okay, before we get carried away close the 2D editor and reopen it again. This will reset the triangle shape so we can get started. Add vertex (it doesn't matter which arm) and then turn the triangle into a square (128 x 128--remember it's a 16 grid). Now you should have something like this:

I hear you saying, "That's great...but how do I make it 3D?" Remember I told you about "extruding or lofting." Well, you're bright, I'm sure you have already seen "Loft" on the menu a the top of the screen. If you choose Loft and then Extrude we can make our box into a cube. You may have to move or resize the 2D editor window to see it, but a dialog box pops up. Don't change Group Name and make sure the Loft Plane Z is checked. On the right for depth let's put in 128. Now click build. Nothing happened in the 2D editor but it just made your brush in UnrealEd into a cube. Close the 2D editor and look at it. You should have a pretty basic 128 sq cube. Now it would be silly to make that with the 2D editor when you have a cube button, but we did a square just to show you how Extrude works. How does it work? It takes the 2d square we drew and "stretches" it up to the depth we indicated in the dialog box. Try another box, this time with a depth of 64.

Okay, Let's make a different shape. Reopen the 2D editor. Don't change anything on the triangle. Go straight to loft-extrude, and set the depth to 128. You should now have a prism shape, or a triangle on it's side that is 128 units tall. You can use this to make a lot of different shapes. Let's build something useful, like an arch. Start by closing the 2D editor and building a room on your map. Make it 256 x 512 x 512. Go ahead and subtract the room and then open the 2D editor. Let's build an arch that is 128 unit stall. Oh no, Math! After years of editing in Doom/Quake/Quake2/Unreal I think in units of 8 so I know that it is going to be 8 boxes on a 16 unit grid. If you don't think in "base 8" then you may want to use a calculator! At any rate, start with a 128 square box in the 2D editor like we made earlier. Now, select the lower left vertex and that should highlight the bottom leg of the box. Now add another vertex. The bottom line should be split in half now. Click and drag the new vertex up until it is touching the new line it created (see below).

Extrude the shape to a depth of 64 and build. Close the 2D window and you should have a rather pointing, small arch thing. You should rotate this so the points are pointing down.

You can add this to your room now. Not too functional as an actual arch (too small to walk under) but you could use it for decorations or something. Try some other shapes, with more sides and different depths to get a feel for how it works.

Other Options

Okay, remember how we had to rotate the little arch thing? That is because we lofted it on the Z axis. That is, we told the editor the object was "laying flat" and we wanted it lofted "up." go in and make the shape again and this time before you loft it, set the Loft Plane to X. This tells the editor the object is standing as it if the bottom of the 2D editor window was "down" and we pulled it shape along the X axis. Now when you build it should be "standing up." Try making a shape and lofting it on the different Loft Planes to get familiar with how the editor uses loft planes to place your object. You are probably curious now what the other Loft options do. We have only used Extrude so far. Logically you should be able to figure out what the others do, especially if you are familiar with 3D models. I will run through them quickly.

Build Sheet: Does just that. Makes the shape a flat sheet. notice there is no dialog box for this lofting option. Revolve: See below Extrude: You already know Extrude to a point: see below Bevel: Works like extrude except it puts a cap on the object. The option to set the depth works just like extrude, and then the cap height option tells the editor where you want the bevel to taper to. It works the same way that putting a cap on a cone works.

Extrude to a Point.

This works like the bevel option only it will taper the object to a point. Think of it as bevel with a 0 cap height. This is great for making pyramid shapes. Simply make a square and extrude it to a point setting the depth however high you want the pyramid.

Revolve

Revolve is cool for making donut shapes and curved hallways. When you are using revolve the editor basically builds the object AROUND the center point (that green cross I mentioned earlier). Open the 2D editor and reposition the triangle vertices until the triangle looks like the image below. Be sure to have the whole shape either left or right of the center point. If you don't and you try to revolve it the editor will warn you (a rare instance when it doesn't crash if you do something wrong!:)

Now go to loft-revolve. In the dialog make sure the loft plane is Z and set the number of sides per 360 to 16 and number of sides to 16. Hit build. You should have something like this:

See how the editor lofts the shape around the center point? The number of sides per 360 obviously tells how many sides it will have in a full circle, and the number of sides tells it how much of the circle to build. If you set the #/360 to 16 and the number of sides to 8 is will build...anyone?....right! Half a circle! An Arc to you and I. Go ahead and try it using different numbers for the number of sides and number/360. But don't do something stupid like 12 sides per/360 and 128 sides. You will only get a stupid result. Going back to our example if we were to subtract that from the world, we would have a room rather round shaped with sloping floors and ceilings and a column in the middle. That column width is determined by the distance you put the 2D shape from the center point. The slope on the floor and ceiling are determined by the angle you have the "top and bottom" of the shape. Imagine the 2D shapes you make are like looking at a cross section of your 3D shape. If we made the starting shape square you would get a flat floor and ceiling. Play with it and see how you can slant the floor, ceiling, etc...

Arches and Doorways

Okay, you have learned a lot about the 2D editor and should have a fairly good idea how it works. Now I will show you a very powerful feature of it. In the 2D editor you can import BMP files to use as a "guide" for making your shapes that align with textures. This is how I (and the Unreal Level builders) make doors and arches. Let's learn how. To start with let's get a fresh map. close the 2D editor and in UnrealEd go to File and New level. Answer yes when it asks you to confirm. Select a texture set...let's use NaliCast.utx Pick a nice wall texture. Now build a basic room 256 x 512 x 512. Now in the texture browser choose ARCH to see the arch textures. Let's pick an easy one. See the very last arch texture (WRC-Door).

You can export this image so we can import it into the 2D editor. To do that highlight the texture and then click EXPORT at the bottom. Name it something cool like WRC-DOOR. If you noticed you can only export as a PCX file. I already told you that you must import a BMP file. So we need to convert the PCX we just saved as a BMP. The easiest way (and most universal since we are all using windows, right?) is to open the exported PCX in Windows Paint and then save it as a BMP. UnrealED exports the file to the Texture directory. Open Paint and find the PCX and open it. Now choose file, and save as and it should default to a BMP and already have it named for you. The only thing you need change is the directory, so that it saves it in the System directory. Once saved as a BMP close Paint and go back to UnrealEd. Open the 2D editor and on the menu go to Image and Load image. You should see your BMP file there. Double click it to open it. Now your arch picture should appear in the 2D editor.

Now we need to manipulate and add vertices until we have surrounded the BLACK area of the image. Do this by lining up the lines with the edge of the stones in the image and add vertices, moving from left to right around the image. Now, you will see that we can't line the vertices up perfectly because the vertex wants to snap to the grid. You can go to Grid on the menu and uncheck Snap to grid to fix this. But this makes it harder to line up the Straight sides.

One you have it like this then go ahead and extrude using Y plane and 32 depth. Now, the arch hole brush should appear in UnrealEd, only upside down. We can rotate this till it's right. Now, we are going to use this brush to "cut out" our doorway. What we need to do now is build a wall to subtract it from. First EXPORT your new brush. Call it NaliArch or something. Close the 2D editor and build a wall that "cuts" our room in half. Make this wall 256 x 32 x 512. Now select the arch texture we have been using and add the wall. Now, we can see that the arch texture is half as wide as our wall. Align your wall (on both sides) so that we have two arches like below.

Now go to Brush and import and import the arch brush. Now align the brush so that it covers the black portion of one of the arches on the wall. Use the 2D views to center the brush on the wall and then slide it until it covers the black portion like so:

Now if you left snap on in the 2d editor it won't line up perfect. That is fine for the purpose of this tutorial. Once you have the brush aligned correctly then subtract it from the wall. You should now have a hole where we want it (the black part should be gone and a hole exists where the black used to be). Now do the same thing to the other arch on the wall. You should now have a room separated by a wall with two arched doorways in it.

What's really cool is that if we wanted to put doors in those door ways, we could use the same brush we used to cut the holes and the doors would fit perfectly! You can add a player start and lights and rebuild and run the map if you want.

Arch Options

Now, if we wanted a true arch we could have simply build a 256 x 256 x 32 wall, floated it in the air (but not in out start room, it's not tall enough!) and put the arch texture on it and then cut the doorway out. We would have had something like this:

Here's a little project for you. Build a room like this screenshot and see how close you can match it using what you have learned today. If you like send me the .unr (preferably zipped!) and I can see how well you did. You don't win anything and this is not a contest. I just like to see what my "students" learn! Note: I only used one (1) brush!

Play around with what you have learned about the 2D shape editor. It's a powerful tool, especially with the lofting options and the ability to import images to align your shapes with your textures. Again you should probably read Myscha's article at Unrealized.

Now, if you can wait until my next tutorial I will show you how to use the FLOOR LOFTER!

©Copyright 1999 Tony Garcia (a.k.a. Wolf). No part of this tutorial may be reproduced without my permission.

Wolf's Unreal


Menus

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Menus:

File Menu

  • File->New
    start a new 2D shape
  • File->Open
    open a saved 2d shape: Note, the file format for 2d shapes is different from all previous versions of the 2d editor, including early versions of UnrealEd 2.
  • File->Save
    save the current 2D shape
  • File->Save As...
    Save under a different filename
  • File->Image->Open From Disk...
    place a bitmap in the background to make your shape around
  • File->Image->Get From Current Texture
    Loads the currently selected texture from the etexture browser into the background.
  • FIle->Image->Delete
    clears the image from the background
  • File->Exit
    close the 2D editor window

Edit Menu

  • Edit->Insert New Shape
    Inserts a new shape in the 2d window
  • Edit->Split Side KEY - CTRL+I
    Splits the currently selected vertex. THe selected vertex is shown by a dark gray line.
  • Edit->Delete
    Deletes the currently selected vertex
  • Edit->Scale Up
    Scales the entire shape up by a factor of 50%
  • Edit->Scale Down
     Scales the entire shape down by a factor of 50%
  • Edit->Rotate 45
     Rotates the shape anti-clockwise about the green pivot point by 45 degrees
  • Edit->Rotate 90
     Rotates as above by 90 degrees
  • Edit->Flip Horizantally
     Flips the shape horizantally, Left-Right
  • Edit->Flip Vertically
     Flips the shape vertically, Top-Bottom
  • Edit->Grid
     Changes the size of the grid, exactly in the same way as main editor.
  • Edit->Segment->Linear
     Changes the current line to a linear line, straight between 2 points
  • Edit->Segment->Bezier
     Change the currently selected segment to a bezier line, great for making the tops of those archways
  • Edit->Segment->Detail
     The amount of points between the 2 end points for a bezier curve, i.e. how smooth it is.

View Menu

  • View->Zoom In
  • View->Zoom Out
    I'm going to let you work these 2 out on your own, cause I'm that kind.

Process Menu

  • Process->Sheet
     creates a flat sheet brush from the current shape
  • Process->Revolve
     rotates the shape about the origin. Options for number of segments per 360 degrees, and how many to produce, e.g. if you choose 8 segments per 360 degrees and only draw 4 the shape will only be half of a full rotation. It will be rotated about the green pivot point.
  • Process->Extrude
     extrudes the current shape (e.g. a square would make a cube or cuboid)
  • Process->Extrude to Point
     Extrudes to a point, come on now work with me... A cube would make a square based pyramid.
  • Process->Extrude to Bevel
     Extrudes to a bevel, which is basically a pyramid with a bit chopped off the top. The Depth is the height of the pyramid and the Cap Height is the height from the base. Therefore is Depth and Cap Height are the same then it is effectively Extrude to Point, and if Cap Height is 0 (which it doesn't actually allow) then it is just Create A Sheet.


Toolbar

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Toolbar

  • New
    start a new 2D shape
  • Open
    open a saved 2D shape
  • Save
    save the current shape to a 2d file
  • Rotate 90 Degrees
    rotates the current shape 90 degrees about the origin (green dot)
  • Rotate 45 Degrees
    rotates the current shape 45 degrees
  • Flip Vertically
    flips the current shape vertically about the origin
  • Flip Horizontal
    flips the current shape horizontally about the origin
  • Scale Up
     scale the shape up by 50%
  • Scale Down
     scale the shape down
  • Zoom In
     Go on, guess
  • Zoom Out
     Zoom out on the image
  • Split Segment
    Add a vertex in the middle of the current selected segment
  • Delete
     Delete the selected vertex
  • Linear Segment
     Changes the currently selected segment to a linear (straight) line between 2 points
  • Bezier Segment
     Changes the currently selected segment to a bezier line, giving you 2 points to create a stylish curve with.
  • Create a Sheet
    creates a flat sheet brush from the current shape
  • Create a Revolved Shape
    rotates the shape about the origin. Options for number of segments per 360 degrees, and how many to produce, e.g. if you choose 8 segments per 360 degrees and only draw 4 the shape will only be half of a full rotation. It will be rotated about the green pivot point.
  • Create an Extruded Shape
    extrudes the current shape (e.g. a square would make a cube or cuboid)
  • Extrude to Point
    Extrudes to a point, come on now work with me... A cube would make a square based pyramid.
    Extrude to Bevel
    Extrudes to a bevel, which is basically a pyramid with a bit chopped off the top. The Depth is the height of the pyramid and the Cap Height is the height from the base. Therefore is Depth and Cap Height are the same then it is effectively Extrude to Point, and if Cap Height is 0 (which it doesn't actually allow) then it is just Create A Sheet.


Making An Archway

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

We are going to make an archway for a specific texture. The texture I have chosen for simplicity is Door2B in the Ancient package.

The first thing you should therefore do is load this package and select the texture.

For the room all we need is a 512x512x512 box subtracted. Then add a 256x256x16 cube with the arch texture. This should give you the picture on the right.

Then load the 2D editor.

To set the texture as the background choose File->Image->Get From Current Texture. This will load the texture into the background of the editor.

The simplest way to create the cut out section for the door is then to move the 4 corners of the square to the sides of the black area and make top segment a bezier curve. If you then move the bezier points to just above it creating a lovely curve you should end up with something looking like that in picture 2. The green marker is the pivot point of the created shape which can be moved and the red marker is the center of the shape and cannot be moved.

You can increase the smoothness of the top line by going to Edit->Segment->Detail and choosing say 10 (I think the default is about 4).

Once you are happy with the shape click on the Extrude icon [image] or choose Process->Extrude and enter 16 for the width (or whatever width you made your wall). You will then have a brush in the world which should fit exactly the hole you have.
Note on Rotation
Often when you produce a shape using the 2d editor the resulting brush will be incorrectly oriented, i.e. on its side or upside down. The simplest explanation is to look at the 3 2D views and decide which on is showing the correct side of the shape. For example the above shape might come out with the Top view showing on of the sides, the Right view showing the top and the Side view showing another of the sides. Therefore you would choose the Side view and holding down the Ctrl+Right Mouse buttons rotate the shape till it was the right way up. This should correct the other 2 views at the same time!

The finished article should then look like the image below.


Making A Corridor

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Making a corridor is actually a very simple task when you get down to it.

Create a room by cutting 3 256x256x256 cubes out in a straight line, then create another room parallel to this but 512 away.

Set the textures to whatever you want but set the middle wall on the facing sides to the archway texture Door2B in the Ancient package.

You should end up with something looking like the picture on the right.

Then load the 2D editor.

To set the texture as the background choose File->Image->Get From Current Texture. This will load the texture into the background of the editor.

The simplest way to create the cut out section for the door is then to move the 4 corners of the square to the sides of the black area and make top segment a bezier curve. If you then move the bezier points to just above it creating a lovely curve you should end up with something looking like that in picture 2. The green marker is the pivot point of the created shape which can be moved and the red marker is the center of the shape and cannot be moved.

You can increase the smoothness of the top line by going to Edit->Segment->Detail and choosing say 10 (I think the default is about 4).

Once you are happy with the shape click on the Extrude icon [image] or choose Process->Extrude and enter 512 for the depth of the corridor.
Note on Rotation
Often when you produce a shape using the 2d editor the resulting brush will be incorrectly oriented, i.e. on its side or upside down. The simplest explanation is to look at the 3 2D views and decide which on is showing the correct side of the shape. For example the above shape might come out with the Top view showing on of the sides, the Right view showing the top and the Side view showing another of the sides. Therefore you would choose the Side view and holding down the Ctrl+Right Mouse buttons rotate the shape till it was the right way up. This should correct the other 2 views at the same time!

You should then be able to move the shape between the 2 archway textures and subtract, creating your corridor. The final product should look something like that on the left.


Making A Curved Corridor

By: Blacksway

www.unreality.org/blacksway

blacksway@unreality.org

Making a curved corridor is almost identical to making a normal corridor, so follow that tutorial first HERE.

The only difference when making the curved corridor is that instead of clicking the extrude button you must click the revolve button.

First however you must set the point to revolve around. This is the green pivot point and should be moved to either the left or right of the image. The further out you go the longer the corner will be.

For completeness sake I've set up a map which requires a curved corridor on the right.

Load the 2D editor and create exactly the same shape as in the previous tutorial.

Next we need to move the green pivot point, I've moved it 256 to the right of the shape as in the image on the right. I've circled the green pivot point in purple to make it stand out.

If you then click on the Revolve icon or choose Process->Revolve.

For the options for this I usually choose 16 peices for 360, and as we want a 90 corridor I've set Use to 4. This should give you a lovely 90 degree corridor which can fit beautifully into the map.
Note on Rotation
Often when you produce a shape using the 2d editor the resulting brush will be incorrectly oriented, i.e. on its side or upside down. The simplest explanation is to look at the 3 2D views and decide which on is showing the correct side of the shape. For example the above shape might come out with the Top view showing on of the sides, the Right view showing the top and the Side view showing another of the sides. Therefore you would choose the Side view and holding down the Ctrl+Right Mouse buttons rotate the shape till it was the right way up. This should correct the other 2 views at the same time!

You should then be able to move the shape between the 2 archway textures and subtract, creating your corridor. The final product should look something like that on the left.

Trust me, it look sbetter when you play the map....


BB Drac - Unreal Tournament UED2 guide 2D Shape Editor

2DShape Editor

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

With the 2D shape editor you can create custom brushes.
Firstly by creating a sheet and then add depth to it.

What you do is that you add and remove vertices and move them around to create the
shape of the brush you want.

Screenshot

Screenshot

You will also see two colored "boxes", which is the real center of the brush and
the actual brush handle.

To move a point around you highlight it and then hold down CTRL, left mouse button
and then move the mouse.

To create the brush and use it in the editor you select one of the possible ways.
Sheet, Revolve, Extrude, Extrude to Point and Extrude to Bevel.
Sheet will create an identical brush as the one you made with no depth.

Revolve will take the sheet you made and create an object that rotates
the sheet around its own center point.
For this to work you need to place the center handle on the side of the brush.

Extrude will add depth to the brush making it a 3D brush with a 2D shape as base.
Depth is the height you want the "sheet" to have.

Extrude to Point is basically the same thing as the regular Extrude but decrease the size
of the "sheet" until it become a point.
The point will be where you place the center handle.

Extrude to Bevel, also almost like the Extrude but more like the Extrude to Point as it
will reduce as more depth it get.
However, instead of getting a point the top will be flat.

This is some of the options you have to easier edit your shape:
Hold the right mouse button and move the mouse around to move the "camera" around.
By pressing the right mouse button on the object you get some options.
"Set Origin" will move the center, or object handle, to the selected point.
"Split Side" will add a vertex to the highlighted side(s).
"Delete" will delete the highlighted side(s).
Under "Segment", "Linear" and "Bezier" will change how you adjust the line between
two points. Default is "Linear".
All these functions have buttons for this on the toolbar and in the menu.

The last and one of the functions you will get most use for when creating
hallways and arched doors is the "Image" selection from the "File" menu.
By either loading a texture from disk or selecting the current texture from
the texture browser you will add the image as a background in the shape editor.
This will allow you more accurate create the shape you need.

Select "Delete" from "Image" when you want to remove the image.

If you try it out for a bit you will see that it is a lot easier than you thought.


Unreal Editor Maximum [unrealism.com/unrealedmax] - 2D EDITOR SHAPES

2D EDITOR SHAPES

The Indian Fakir a.k.a "Machismo"

www.unrealism.com/unrealedmax

cool_machismo@yahoo.com

INTRODUCTION

This tutorial will show you how to make a basic arch and complex curved passages using the 2d editor and some other cool shapes that can be done. This is actually more of a series of series of 20 screen shots that will show you how to get the stuff done. I expect you to be quite familiar with the editor and the 2d editor.

UNREALED2 Note: I am assuming that you are using version 436.

DOWNLOAD NOW : You can grab a little zip file here that contains all the shapes made and used in the tutorial. It also has some other weird shapes that you can use and screw around with. Mirror Download (From Geocities) .

THE BASIC ARCH

1. Load the skycity.utx texture package which has a very nice basic arch (to see all the arches of that package in the drop down menu below choose arch) - skycity as usual has some really great ones. (v436) We are going to use this picture to make our shape in the 2ded. Select the arch and then open up the 2d editor (from the tools menu or by hitting the 2deditor button). Go to file menu, scroll down and from image hit "get from current texture" and the arch image automatically gets loaded into the 2d editor.

2. It should now appear in the 2ded like this:

3. You can stretch the leg of the square by clicking and selecting the white highlighted vertex. The chosen edge will be highlighted by a red square. You can select the other leg by clicking the edges. Stretch the legs of the square so that it touches the edges of the picture like this:

Please note that to make the picture more distinct I have held down ctrl and selected all the edges - don't expect to see something like that. These four legs will be called the base legs. No matter how their size changes keep track of the bases so that you know what I'm talking about. The aim is to create a 2d shape that covers the entire brown (empty?) region of the arch.

4. Select the top most leg of the square by clicking on one of the vertices so that it is highlighted and hit ctrl+i or edit split side. This will divide the top half of the square into two equal half's. It will look like this:

Note1: I have highlighted the single vertex that I selected before hitting ctrl+i.
Note 2: You will find it difficult to align the sides just right click anywhere in the 2ded and turn down the gird. I have to say though its more convenient working with the gird set at 16 for curved shapes as you can get exact measurements.
NOTE 3: To move around in the 2ded hold down the right move button and drag to move around.

5. Move the newly created vertex to the place on the picture where the straight part of the picture ends and the curve begins, like this:

6. Ok for now leave the vertex selected in the above picture. Hit ctrl+i and split that side so that the shape looks like this:

7. In the same way by selecting the new vertex and the old I added in 6 other vertices and then moved them up one by one so that the shape became like this:

Note: I have just selected all the vertices so that the picture is more distinct don't expect to get something weird like that in your shape :).

8. If you've followed all along and got the above shape jump to the next step, if not read on. Still having problems and unable able to get that shape?, want to blow my head off for not explaining straight?, not to worry help is at hand. The 2ded requires some practice to get the hang of it. Save the picture in the previous step as a bmp. Load it in the 2ded and try to work out the shape by following along. That should have helped you solve the problem. There will be many lines running around so you may get disoriented, if so delete the image using the file menu reorient yourself and then load the image.

TIP: I have explained this in a way so that you can get your first arch shape easily. After some practice you should just add in how many vertices you need and then move them at one shot, not add three and them move, etc. And who ever said the arch shape needs to conform to the picture, take a close look at the arches in DM-Curse to see what I mean.

9. Under the process menu hit extrude and in the dialog box that opens put in a depth of 32 - which determines how thick the arch will be. Leave everything alone for now. Hit build and your brush should appear in the level on its side which you will naturally have to rotate .... always for any shape you create in the 2ded.

10. Leave the 2ded alone for now. Now we'll create a room for the arch to be placed in. Subtract a brush 256x256x512. Build a brush 256x256x32 and add it into the middle of the room with the arch texture that you used. Hit the extrude button from the 2d editor to get the shape in you level. Rotate and align it so that it covers the brown part of the arch exactly. Intersect if necessary and hit the subtract button. The arch you ordered:

There you go, you have a nice beautiful arched doorway.

CURVED PASSAGEWAY/ROOM/STUFF

Curved passages should not be created using vertex editing (although you could do it). Man it would be like wanting to ride along in a cart when you could actually zoom along on a Ferrari!. Well that should have made you quite familiar with the 2ded. Lets see how to make one of those nice curved passages that seem to be used in nearly every level (like Zeto, Liandri, etc.). Oh man this is going to be so simple to do but the results that you will get are going to make you go - wow that was easy!.

First hit file new and set the green origin to the left or the right of the square like this:

[Note- If you were to extrude the shape you would get a perfect 256x256 box!]. Hit the loft, revolve menu and set sides per 360 degrees to 24 and number of sides to 12. Hit the subtract button and check out the shape you got. If you were to set sides per 360 to 24 and number of sides to 24 you would get a completely curved room. Play around with this value to see the different shapes that you can get. Here's how it should look:

Well for some the mantra may be "location, location, location" but here's mine regarding curved rooms:
1. First get the damn shape you want worked out in the 2ded.
2. Set the crosshair at an appropriate distance from the shape. The further you move the crosshair to the right the more the shape starts to lose its " small inner curve" and resemble a stretched one. The closer you move the green crosshair to the shape the more the curve seems to "collapse on itself". Try moving the crosshair around to see the effect.
3. The values you set in the revolve box will affect the final brush drastically.

In conclusion how does the 2ded handle revolved shapes?. You can just think of it taking the 2d shape and sort of joining it together in sheets to create the final shape just think about that and you'll probably get the point (well at least I hope so :). Ok listen up people with this part I am going a little overboard, lets see how to get some complex revolved rooms.

1. DM-Zeto: The first order of the day, let me dispel some myths. The shapes are quite simple to create once you get the hang of it. Here's the final shape in the 2ded (see below for how I got the shape):

The shape works somewhat on the same principle as the arch. Just split the top part of the cube 6 times and move the vertices to the positions indicated above and you'll get the shape.
a. In the arch that we created before you will notice that all the vertices seemed to emanate from one vertex but in the above picture I have highlighted the vertex that causes the shape to change drastically.
b: You'll notice that the shape has been created using attention to detail - all the vertices are at precise 4 units away from each other. What's the big deal with that?. Texture alignment can be a real bitch if you make the shape without consideration to such stuff.
c: WARNING: These shots were taken in the old 2d editor and are probably here for unknown reasons if you were able to get the shape in the previous pictures just ignore this step as it could get you more confused.

This is for those of you who like to be babied, a series of shots showing how it was done in the first place:

In Step 1 I created the first part of the shape by splitting one side over and over. In step 2 I shifted sides and split the ones that I have selected and moved the vertex around. Check out the next picture - selecting those two vertices and splitting them will take you to the picture in step 3. And selecting the two vertices that are highlighted in step 3 and splitting that will give you the final shape that I first showed you.

Now revolve this baby and see what we got:

Not quite DM-Zeto but close enough to see the similarity. Got the point?.
2. PIPE DREAM: Shape in the 2ded and its result:

What the hell am I showing you a stupid pipe for?. Well this really illustrates a thorny issue that you will encounter while revolving shapes. Alignment of vertices, etc. You will need to be comfortable with vertex editing (very very comfortable in fact). Another point that you should note is that I extruded and then revolved the shape so that they connected up perfectly.

3. Some Standard Shapes/Rooms/Stuff you can do:
IMP. TIP: Whenever connecting revolved rooms you will encounter ugly shapes. To resolve this extrude the same shape that you have used to revolve a passageway when you want to connect it.
a. The purpose of showing you this simple shape?. I just wanted to illustrate the point that you could do some awesome stuff with some very simple shapes!.

Notice the step like roundedness of the beginning of the room and how I connected the revolved room with an extruded shape. [This is how I did it - revolved the shape 24 sides per 360 use 1; next in the 2ded I just moved the bottom of the shape down one unit (remember the gird is at 16 units) and revolved it using the same settings again, this ensured that my step had a perfect height of 16 units; I did this several times and then just extruded the same shape so that I could connect the revolved room perfectly and viola we got one cool room!.

Do I need to explain further?. I think not buddy, you should now be able to create just about any rounded passage that your mind can conjure up or anyone can think up. In my opinion the 2ded is the most important part of the editor once you have mastered it maps like DM-Zeto should be a snap. Now all you need to get good reviews is get creative that's all I can help with at this point.

MERGING CO-PLANAR POLYGONS:

You would have noticed something in the shapes that you get in the 3d view after revolving the shape in the 2d editor and subtracting it. They all seem to be broken into smaller pieces, thus:

I was able to select a part of the floor, a part of the wall and a part of the ceiling separately. This is bad editing and raises the node/poly count that mappers always try to keep down. So you need to rectify this. First select a part of the floor, right click, scroll down to Select Surfaces and under that menu select adjacent floor ceilings, or you can simply hit Shift+F. This will select all adjacent floors. Now go to surface properties of these textures -from the View menu surface properties or hit F5 or the surface properties button. Under the alignment tab hit align to floor so that the surfaces are aligned properly. Do the same for the ceiling of the room. Now select the wall (all the little pieces that it is broken into) at the end of the curve. Go to the surface properties and hit first wall direction and then wall pan - don't forget to do both. Do this at both ends of the curve. Now select the subtracted brush in the top down view, right click and scroll down the menu to POLYGONS and under that menu hit MERGE. Now rebuild the level and select the end wall, it has become one piece, like this:

 Nice, clean and fixed!. Its a great idea to do this to every shape that you make in the 2d editor (actually you need to do it for visible surfaces only). Another way of getting rid of these broken parts (use only on extruded shapes) is to intersect it against a flat surface. try this for any extruded shape.

BEZIER SEGMENT

You can create arches using bezier segments. This is actually easier but I wanted you to get used to the vertex move method before as it is convenient for getting to know the 2ded better. Turning a segment into a bezier segment is easy. Try this select the top of the default cube and hit the bezier segment button [image] to turn that segment into a beizer. You get two control points just select one of them and move them around to see the shape bend in that direction.

This is really convenient for creating curved shapes (note not curved rooms shapes that are sort of round). You need to experiment with it to get some good results.

NOTE: I hope you downloaded the zip file. if you look under the SkyCenter folder you will see that a lot of the shape have been done using beizer segments (especially the lockers). Check it out now!.

Now take a look at this final shape - the round parts of the shape have been made with 2 beizer segments (i.e. with a total of 4 control points). Note: The texture is from ShaneChurch.utx.

SCALING THINGS

This is a very convenient button. You can just create shapes in a small scale and then just hit the scale up button to increase the size. Its like working in miniature and then just scaling the shape up to a huge size. Great for creating outdoor detail.

TO DO LIST

  • Not all of us have a copy of 3D Studio MaxR3 lying around. But you can still make great outdoor levels with just the 2deditor. Just take a look at AS-OverLord to see what I mean. The entire mountain near the beach was made in the 2deitor. And if you just use TerraEdit along with it you can make superb outdoor levels. AS-Overlord is a great example of how to make good use of the 2d editor, virtually every non standard shape that you will see was made in the 2d editor. Remember to use bezier segments to give out door levels a realistic look.

  • The extrude to bevel from the process menu allows you to make shapes like this:

    Notice how the shape slopes up and plateaus. (In the pic depth is 128 & cap height 32).

  • Load the Skaarj.utx texture package and try working out the E_Dr3 door. HINT: You need to make the door using three distinct brushes. In this case you need to make 3 2d shapes for the left, right and center pieces and then extrude them. Just like you would do for arches the best way to do doors would be to work the shape out in the editor. This is how the door will look like in the 2d editor:

    If you have any problems getting the shape done, remember save the picture above and try to work it out on this one. I used the same vertex adding technique that I explained above. When you have extruded the shape, export the brush, add in the complete doorway, import the previously exported brush and place it over that part of the door way and intersect if you need to and copy polygons to brush. Subtract from this shape or make a mover out of the intersected brush or just do what the heck you feel like with the brush :).

  • Work out curved rooms they are the most important part. It would look very nice in your level if you were to connect passages using curved rooms that have been revolved, instead of using the normal cube. In fact I would suggest that you do this always. If you look at any pro maps that's how they have done it.

That's the end of this tutorial. If you are still having problems and want help, you can always reach me ViA my email add.


Tutorials by EZkeel

2D Shape Editor

by Simon 'EZkeel' West-Bulford

Ezkeel@nikodemus.co.uk

Downloadable files: 2D.UNR

Contents

The_Menu
Preparation
Building_your_shape

Introduction

This tool enables you to make brushes in various different shapes without causing some of those bad visual problems you get. I used to build a cube, or cylinder and then move each vertex to get the shape I wanted. But when you do this, weird things can happen. You don’t have this problem as often if you use this tool. Don’t be put off by the word "experimental", I haven’t had any unexpected problems with this so far.

Again, as I’ll admit in all my tutorials, I’m no expert, but I’ll share with you the parts that I know.

1) The Menu

Before actually making any brushes with this, we’ll take a look at the actual menu functions in this tool.
Open the 2D Shape Editor by clicking on the "2D" icon in the menu bar.
You will see another window open that looks like a grid with the outline of a triangle in the centre, and a menu list at the top. Before taking you through step by step I'll give you a very brief overview of all the functions in the menu. They may not make much sense straight away but it should all fall into place by the time this tutorial has ended.

File Has all the usual functions like new, save, save as and one extra tool which is very useful ...

Open Image Very useful. This enables you to load a bitmap image on to the grid and use it to trace an outline. This enable you to get a perfect fit for your brushes.

Edit Includes the following functions:

Split Side: This will add an extra vertex in between two other selected vertices.

Delete: Removes the added vertex

Rotate 45 and 90: Both these functions will rotate the shape

Flip horizontally and vertically: Again this just moves the shape accordingly

Process includes all the commands that you use to give a third dimension to your flat shape.

Sheet: Makes a 2 dimensional sheet in the shape you’ve just created.

Revolve: Oh this is useful! Create your shape in the window, but make sure that the little green square in the window is either way left or right of the shape. If its in the middle of your shape somewhere this won't work. What this does is very neat and as soon as you use this option you'll see just what you can do with it. Once you've positioned the green block, hit the revolve option and take a look at the new window that pops up. Type in somthing like 24 in the field that says "per 360" (this refers to degrees) and in the field that says "use" type in 6. Then hit OK. The brush that appears will look like your shape but pivoted around the position you put the cross at for 90 degrees. See what I mean? Play with it and see. Its awesome for making twisty passages.

Extrude: This will turn your shape into a 3 dimensional object, by giving it depth. When you choose this function, a box appears. It will give you the option to "extrude" it to a particular depth (default 256). So a square shape would then become a box.

Extrude to Point: Again, the same as above, but it brings it to a point instead of just stretching it out. (e.g. a square sheet will become a 4 sided pyramid).

Bevel: Similar to the extrude functions. This extrudes to a point, but stops short of reaching that point. (e.g. a square sheet would become a 4 sided pyramid chopped off half way)

All of these functions can be found on the icon tool bar just underneath too, and some of them by right clicking the mouse.
The mouse also allows you to change the grid size and if you hold the right button down and drag, you'll see the shape move around in your window so that you can position it centrally.

2) Preparing to make your shape.

Now you’ve been given an overview of the functions available you can have a try at making your own archway.First make a large, lit room, say 1024 x 1024 x 1024, and add a player start. Rebuild it and save it. We are going to put a bricked arch shaped corridor leading from this room

We need to know what shape our arch is going to be, so first we need to make some preparations.

Load in the texture file called "Ancient.UTX" and the subgroup called "Arches" should already be showing. Choose the arch that you would like to use and make a brush the size of this texture to fit snugly against the wall (say 256 high, 256 wide and 16 deep).

Add this to your room, rebuild and save.

You should now have a big room with an archway in the wall. Obviously the entrance of the archway will just be black and this is what we are going to hollow out.

The texture you used for this archway will also be used in the 2D editor, so we need to "export" it. To do this, choose export from the options at the bottom of the texture toolbar (make sure you have your archway selected in the toolbar). Now save the texture, it will be stored as a PCX format.

Unfortunately, the 2D Shape Editor won’t use PCX pictures, so you’ll need an application that will convert your PCX file in to a BMP file! (If you can’t do that then you’ll have to guess the shape of your arch later on, and use trial and error). You’re now ready to play with the 2D Shape Editor!

3) Building your shape.

    1) Open the 2D Shape Editor.

    2) Now click on "File" from the menu options and choose "Open Image". A browser will appear from which you can choose the BMP file you prepared earlier. Once you’ve selected that, the archway should appear on your grid.

    3) Click on each of the bottom two vertices and drag them so they fit the bottom of the black part of the archway.

    4) Click on the top vertex of the triangle and drag it to the top of the arch. The side that slopes down to the left should be slightly thicker than the other two lines. You won't see this because the lines that make up your image are black like the masked part of your texture, but you can still see the vertices. Now click on the top vertex at the top of your arch, and also on the bottom left vertex with the Ctrl key pressed down. Both vertices should turn red. Right click and choose "split side" from the drop down menu. You should see a new vertex appear with between the two selcted ones.

    5) Now click and drag this new vertex to the next part of your arch on the left that starts to curve.

    6) Continue steps 4 and 5 until you have enough vertices to mimic the outline of the arch.
    Hopefully you should have something that looks like the picture above:

    7) That’s most of the work done! Now click on "Process" and choose "Extrude". A small box should appear somewhere on your screen (probably behind the editor!) like this.

    8) Choose your depth and then click OK.

On your normal editor screen you should now see your red brush in the shape of your archway. Position it (rotate it in one of the views if necessary) so that it meets the edge of your arch brush that’s in your room. It should look like it fits snugly in the 3D view. (You may have to change the grid size to do this). Then click on the "subtract" icon to add this to your map (2nd button down on the right of your icon toolbar). You should now see your amazing arched hallway extending from your room. That’s it!

You may also want to experiment now using the "Bevel", "Extrude to point" or "Revolve" functions.

Ezkeel.
Ezkeel@nikodemus.co.uk


Curved Objects

By: Deathman

Deathman

Making curves is all done thru the 2d editor.

ARCHES

Notice the archway texture Door2B in the Ancient package? You can make a arch to match the texture!

First, subtract a 256x256x256 brush. And make another room (don't put them together). Subtract the other room. Get the builder brush and form a hallway to connect the two rooms but don't subract it yet. Be sure the height and width is the same as the rooms. (256x256) Select the wall facing the hallway and apply the door2b texture to it. And the other wall facing the non subtracted hallway in the other room.

Now its time to apply a arch to the hallway-(builder brush).

To do this, select the texture in the texture window, (door2b)

open up the 2d editor:

To set the texture as the background choose File->Image->Get From Current Texture. This will load the texture into the background of the editor. Sometimes, the editor will crash if you do this. If it happends then continue reading this tutorial. I provided a file that will have everything set up for you.

Read this if no probems occur:

The simplest way to create the cut out section for the door is then to move the 4 corners of the square to the sides of the black area and make top segment a bezier curve. If you then move the bezier points to just above it creating a cool curve. Be sure you move the bezier points to align the curve over the arch on the texture.

You can increase the smoothness of the top line by going to Edit->Segment->Detail and choosing say 10 (I think the default is about 4).

choose Process->Extrude and enter 512 for the depth of the corridor.

The builder brush should have a arch for the ceiling. You may need to rotate it to connect the two rooms. Now subtract.

Now you have a arch, you can do it without the door2b texture. I just thought the texture could add a little kick to it.

CURVING HALLWAYS

This is really easy: build a 256x256x256 builder brush, open the 2d editor. You should see the plain cube. Now move the green dot in the middle 30 times to the right. choose Process->Revolve

In the first column, put 16 and in the second column put 4 for a 90 angle and 8 for a 180 angle curve hallway.

I hope you can understand this, please let me know if there's any problems :-)


How to make Curved Archways In the 2dSE

2dSE Pt. 1

Jason Pharis-Pina

jimmerjammer411@planetunreal.com

http://www.planetunreal.com/ivebeenfragged

How to make Curved Archways

Now make a room 256x256x256 and texture it how you want using the Ancient.utx pack. I did mine like this:

First Open Up the 2dSE by clicking the icon in the top that looks like this:

Then inside your Texture Browser Open up the Ancient.utx pack. And Select then select the Arch texture Door2b. It will look like this:

: An easy way to do this is type Door2b in the Filter.

Now to make this easier Right-Click the texture and goto Export to pcx, like this picture:

Now for some weird reason textures are exported to pcx when the 2dSE will only take BMPs. So now you have to open up the image in a image editing program. I use Psp7, so Id press F12 and and the pulldown menu I press 'W' 5 times so that 'Windows or OS/2 bitmap' and click save. If your using Photoshop or something else, i cant help you there, I expect that you already know how to use that program.

Now with that done goto the 2dSE window and click file and goto Image and 'Open From Disk' now select the newly made BMP image. When that is done your 2dSE window should look like the second image.

Now we make our shape. First select one of the bottom corners, then drag it over like the followning images. when its done it will look like the second image.

Now onto the top part of the shape. Select one of the top corners of the shape and drag it so that it is about 128 units from the bottom. If thats hard to under stand look at the following images.

Not too hard, is it? Well now heres where we make the curved top portion of the archway.

Select the Right-Top corner of the shape, like in the second picture above. the top line will be Bold Grey. With that selected Right-Click and goto Segment then goto Bezier. Like this image.

After that is done you will see a blue line with 2 boxes on the end, very similar to the corners of the shape. Now Click and drag the Left line up 5 grid points and then Left 1 grid pont. The Same to the Right side, except drap it to the Right 1 grid point, instead of Left. They will look like these images.

Now all you have to do is click Process and goto Extrude. In the dialog box type 256. Like this:

Now you will knotice that your shape is facing all weird directions. goto the side view and click one of the vertexes on the shape, and Left Click Drag so that the shape rotates. Rotate it 90 degrees so that it looks like this in the side view.

Now line up the archway with one of the walls of the room and center it with the floor. I just lined up the center vertex of the archway with the center of the room. Then subtract and texture the wall around the archway. it will look something like this when textured.

There you have it! In the next Part of this tutorial I will explain how to make Curved Arch Hallways.


2DSE Pt

2DSE Pt. 2

Jason Pharis-Pina

jimmerjammer411@planetunreal.com

http://www.planetunreal.com/ivebeenfragged

This tutorial is intended as a continuation of the first 2D Shape Editor tutorial, so if you havent read that one go there now.

Ok the first step is with your 2D shape made and the bezier curve done it should look like this. And make sure that you have a room 256*256*256 made as well.

Ok the first step is to select the Green square, it will turn Red like this.

Now here you have to drag the Red square to the Left or the Right of the shape. I clicked the Minus magnifying glass to zoom out then I dragged it to the very edge of the Image, like this.

Now to make the curve you need to click the revolve button or click Process-->Revolve. the revolve button is crcled in orange.

After you click that you will be presented with a menu thing. Enter the values shown.

Then click OK.

Now in side view you will knotice that the shape is facing a weird direction, well you need to select a vertex and Ctrl+Right click drag, move your mouse Left and rotate the shape 90 degrees to align it.

Now in the top view Rotate it and Center it to the floor like this.

Then Subtract and textrure it how you please.

There you have it, a nice curved hallway. Have fun!


Pathnodes

    Sharky
    jneta@ez-net.com

    First off I hope you know how to use the editor and understand the basics of good design and weapon placement. Also you should know how to add actors to your level.

    First, take a level that is setup the way you want it to look. Make a backup of you level. Then go to classes and under NavigationPoint find pathNode. You start adding path nodes by figuring out the best path through you level. Start placing them far enough apart that they are evenly space but close enough that they are visible from one another. Also try to go past the weapons in your level (when you generate the path it will connect to the weapons). Now that you have all your nodes evenly spaced go into the 3d view and "walk" through your level and make sure they are visible as you go from node to node.

    If you have any elevators/lifts in your level you must place a lift exit where you want the bot to wait for the lift/elevator and a lift center where the lift is on the ground. Next you assign their lift event to the name of the mover's tag.

    If you have any Portals in your level you must place a node inside the portal on each side or the bots will not use the portal. I'm not sure about how teleporters work yet but ill add to this once i figure it out..

    Any doors you have in your level should have path nodes right next to the door if you want the bot to use the door.

    Also if you have any dead end hallways the bots will probably not go down them unless there is a weapon at the end

    Now that everything is setup as you want it. Hit f8 to bring up rebuild and go to the lighting tab and click on generate path. Rebuild your level and you should be all set to play it with bots.

    Well that's it for this edition of the path node tutorial... i will add more to it when i get a better understanding of how they work and any little tricks i figure out about them will be added


Basic Pathnoding

Basic Pathnodes

By trevelyan

-----------------------------------------------------------------------------------------------------------------------

Presumptions:
That you know how to make a map, add lighting and weapons, and don't have a clue as to how to make bots do what you want in a match.

Forward:
A quick explanation as to how the computer opponents (or "bots") work: Every bot in UT and Unreal have pre-programmed actions that are not changed. When it knows a pickup or weapon is nearby, it will usually grab it immediately. When an opponent is within sight, depending on the settings, it will attack in a pre-assigned manner. (Jumping, strafing and firing) When nothing is nearby, the bot will remain still, and actually pace around a little. What pathnodes do is force them along set paths, in straight lines.

Now on to the tutorial already!
OK, first you need to make 2 rooms; roughly 500x1000, any height. Subtract both rooms and intersect a hallway between the 2 rooms, making the hallway considerably narrow. (See the picture below) Go into your Classes window (on the right hand side) and add your playerstart actor and some lighting. Make the playerstart on the end of one room, and set a weapon or pickup (Under Inventory) behind the corner of the other room. (So if you were walking down the hall in the middle, you would have to round the corner to see it)

Now, go into your classes again, and highlight "Navigation Point> Pathnodes". (Yay!) Right click in front of the playerstart actor (the little joystick icon) and click "add pathnode". A little apple should appear (why an apple I'll never know; must be a temptation thing.)

In this case, you would want to add the pathnodes directly through the hall, meeting into the other end. The picture above is in the other end of the map, where the weapon is. Now if we ran this map with a bot right now, it wouldn't function quite right, for 2 reasons. First, we didn't define the pathways; second, the pathnodes aren't set up quite right in this picture, even with this level of simplicity.

First thing's first however. Hit F8 to bring up your rebuilder. You are probably used to just hitting "Rebuild Geometry", as it does most of the work for you. Instead, click the far right tab (Lighting) and click on "Paths Define", located near the bottom. You won't notice anything until you set up your 3D window to show pathways. Simply click on "View" in the 3D window and click on "Show Paths". You should see something like the picture below:

(Notice the blue and red lines? Those are your paths.)

Now everything is set but one thing. It's better to learn the right way first-hand, so observe closely. The pathnode in the hallway is not in visible range of the rocket launcher. The bot in this map will run to the pathnode in the center of the next room, and then run backwards to the rocket launcher.

No real biggie at first, but a quality map must have bots that behave like humans. Humans don't run back and forth like this one will, so a little more work is needed here. (Most likely you did it right the first time around, but this example will help you anyway)

Now, all that is needed here is the pathnode near the center of the above picture to be moved ahead slightly. Re-define the paths using the Rebuilder. This will create another path, having the bot run straight for the rocket launcher, and then proceeding to the center…

(Hooray! Now it's properly set up! (In actuality, another pathnode closer to the weapon would be a good idea, especially if you are to place ammo there.))

It's an annoying but good practice to "run through" the pathnodes in the 3D window, making sure each one is within sight of another, and is easy to get to. Always make sure that pathnodes form a pattern through a map, and never use weapons as paths themselves; if the weapon is gone for some reason, the path is cut, and another path should be available to it. Also note pathnodes do not work for elevators, but do work for teleporters. Elevators require a Liftexit and Liftcenter, which will be covered later on. It is most important to not overdo pathnodes; you usually don't need multiple paths is say, a hallway or small room. As mentioned earlier, when confronted the bots will move off of these paths and attack, usually furiously. The purpose of them is to guide them through when they are "mellowed out", for the most part. In other words, KEEP IT SIMPLE!

Any questions or comments E-Mail me at connors@nnex.net. I would be glad to help out. Until then, happy frags!


Advanced Pathnoding

By: Sliencer

utcity@planetunreal.com

UT City

Topics:

  • Pathing movers such as elevators
  • Making bots take different paths in Capture the Flag maps
  • How to make bots use portals correctly
  • How to create teleporters correctly
  • How to make Jump spots
  • How to use Kickers
  • Making bots snipe and defend correctly

Foreword:

I am suspecting that you have some sort of level ready and are familiar with UnrealED 1.0 or UnrealED 2.0.

Directions:

Pathing movers such as elevators:

Ok, lets start out by you already having a mover ready. For this section I will be teaching on pathnoding bots to use movers, so an elevator would be the best choice to pick. Now open up your Classes Broswer. Go into the Navigation objects. Then look for the following two objects: "LiftExit" and "LiftCenter". See below for visual:

Ok, now click on the LiftExit object and go into your 3D view. Place the LiftExit where you want the bot to get on and off. One will be at the top, and one at the bottom. Make sure it is fairly far but not to far from you elevator/mover. Make sure you place two of those. Ok, now go back to your Classes browser and select on LiftCenter. Now carefully place your LiftCenter right over the center of your lift. See below for an example.

Once you have gotten all these set up, it should have a similiar look to this:

Ok, now it's time to get it set up. First go into your mover's properties. Set the tag to something unique and remember it. Now go into the Object settings and under InitialState, choose StandOpenTimed. This makes the mover go when a person/bot stands on it. See below for visual:

Now close the mover properties and open up the LiftCenter properties. This time go into the LiftCenter settings (found in the LiftCenter properties box) and next to LiftTag, put it as the tag you used for your mover. See below for visual:

Now go ahead and close the LiftCenter properties and select on both LiftExit object in the 3D view by holding the Ctrl button down to select the second one. Right click on one of them and go into their properties. Under the LiftExit settings (found in the LiftExit properties box), go to where it says LiftTag and set that again to whatever it was you set your mover's tag to. Again, see below for visual:

Now close the LiftExit's properties box and deselect them. Now go ahead and redefine paths. To do this in UnrealED 1.0, press the F8 key and go to the last tab and select on Paths Define. To do this in UnrealED 2.0, press on this button [image], which is the Compute Paths button. When that is finished, go to your 3D view again and right click on the gray bar just above it. Then go into View and select on Show Paths. Visual below:

You should now see two or three blue lines, one connecting the bottom LiftExit to the LiftCenter and one connecting the top LiftExit to the LiftCenter. This is good. If you do not see them, you probably tagged them wrong. See below for an example of a correctly done one:

Ok cool, your down. Now just rebuild gemometry, or if in UnrealED 2.0 rebuild geometry and lighting and test it out to see if it works. Good luck!

Making bots take different paths in Capture the Flag maps:

Now this one took me some time to really figure out, but I finally got it. Anyways here is how to do it. First open up your Capture the Flag map or whatever map you want to try it on (CTF highly recommended) and open up your classes broswer. Now before you select anything in it, go to the midpoint of one of your paths in your CTF level. Making sure that you are near or are at the midpoint, remove some of the pathnodes in it. Now you should have a gap in your path. Ok, now go back to your classes broswer and go into NavigationPoint. Then select on the AlternatePath object. Now place one on one side of your midpoint gap and the other on the other side. Basically what you should have now is a path that has two alternate paths connecting it in the middle. Now if you want you can add a pathnode directly in the center (never figured out if it was neccassary but it might be so put one in anyways). See below for a visual of what I just attempted to explain:

Once you have that down, do it for every path in your CTF level. Once you are down with that, assign half of the AlternatePaths their team number. To do this, first select on the AlternatePath that is closer to the blue base (This would be team 1), now select go into its properties. Under AlternatePath, set the Team attribute to 1. See below for visual:

Now do this for each set of AlternatePaths in your map. Remember to only assign the Team attribute to the AlternatePaths that are closer to he blue base. Also note: If you assigned the red base as team 1, then choose the AlternatePaths that are closer to the red base and set their attributes to Team 1. When you are finished with all of that, redefine you paths and rebuild geometry and lighting and test it out. Good luck!

How to make bots use portals correctly:

Before I begin with this section I would like to clarify that you have already made your portals and have placed the WarpZoneInfo's into the portals themselves. In this section, I will only be teaching you how to pathnode them correctly for bots.

Basically all you need to do is put the pathnode in front of the WarpZoneInfo on both sides of the portal like so:

<--This is one end
<--This is the other end

Well I think that's it. After you've done that just go ahead and rebuild geometry, lighting, and paths and you'll be all set. Good luck!

How to create teleporters correctly:

For this section I will be focusing on pathing visible teleporters, but this can also be done the same way as normal ones can. First start out by placing the teleporters where you want them. Next select on one of them making it turn greenish. Now you should see a small red arrow pointing in some direction. Hold down the right mouse button and the Ctrl key to rotate it. This red arrow is pointing to the direction that the bot/player will exit out. Position the teleporters' arrows to allow the player a good view of the battle when he comes out of the teleporter. This is about a five second process but has been known to be done in two seconds :) Anyways, that's how to do it.

How to make jump spots:

Coming Later

How to use kickers:

Coming Later

Making bots snipe and defend correctly:

A question that arises a lot in the UnrealED forums is how to make bots snipe in custom maps. Well, I think it's time to end it with a written tutorial :) First, open up your level and go into the classes browser. Go into NavigationPoint, then into AmbushPoint, and select on DefensePoint. See visual below:

Now place the defensepoints in the areas in which you want the bots to defend or snipe. Since we are talking about how to make bots snipe, I will explain this first. First click on the DefensePoint and right click on it. Go into its properites. Then select on the plus sign next to AmbushPoint and set the bSniping option to True. Then click on the plus sign next to DefensePoint and set the Team number this defensepoint will be for. I am setting this defensepoint up for team blue which is team 1, so I put 1 next to Team. If setting this for the red team, leave it at 0. (Note: If the bots don't use the right defensepoints in the game try switching the numbers around.) Now next to Priority, set it to a number. I am setting mine to 101. Let me explain why this is important.

Let's say that you have three DefensePoints for each team in your CTF map. One you put down as a 50 priority, one as a 51 priority, and one as a 52 priority. Then you start up you level and assign two bots to defend the base. The first bot will go to the defensepoint that has the highest priority number. The other bot will go to the next one down unless there's a second DefensePoint with the same number. In this case the two bots would be covering the DefensePoints with the priorities of 52 and 51.

Ok, now you should understand the concept of the priorities in DefensePoints so I'll be moving on. For an example of how I configured my DefensePoint, look below:

Ok, the next and last part is to position the arrows within the DefensePoint, so that the bots will know where to look. Click on the DefensePoint in your map, you'll notice a small red arrow in your 2D views pointing somewhere. This arrow is showing where the bot is going to look. If you have made you DefensePoint in a tower (like mine), and want it to be looking down at the ground below, just move the red arrow so that it is looking in that direction. To do this, hold the Ctrl key and the right mouse button and drag it around. Do this for every DefensePoint in your map. Below is an example of how one of my DefensePoints looks.

Conclusion:

You should now be familiar with pathing unique things for bots, such as evevators. Most of these techniques take time to master so don't fret if you can't do it the first time correctly.

Other:

-=[Copyright/Permissions]=-

Questions/Comments email me at Murphy149h@mediaone.net .

This tutorial is Copyright (c) 2000 Matt Murphy.

This tutorial is not supported by Legend Entertainment or Epic Games.


BB Drac - Unreal Tournament UED2 guide Bot AI Basics

Bot AI Basics

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

This Bot AI guide will go through the main basics of Bot behaviour.

Also check the Bot pathing tutorial for more info.

Two words is all you need to know and that is Reason and Design.
If there is no reason the design is fault.

I will explain...

When starting, a bot select a destination and try to go the fastest possible way
to get there.
That means if the level has dead-ends and nothing to pick up at the end, bots will
in most cases never go there.
If two paths exist to a specific item and one is much longer than the other, bots will use the
shortest path each time.

In most cases they will get to their designated target without problems.

In some cases though, bots tend to suicide themself trying to get where they want.
Jumping across lava and fails or walking into traps or like.
Bots will never pay attention to this and kill themself each time trying to get across.

As stated, bots pick a single target and try as best as it can to get there.
Along the way it will pick up most items, if they find it useful.

If it fails to complete its route it might try again until it is successful or another
item gets more interesting.

If a bot "falls" outside the definded paths, either by falling off a ledge or after a
firefight, the bot will seek the closest pathnode and from there decide on it's next way.
If the bot fails to "see" a pathnode in the area the bot will camp, wandering around.

When bots walk across ledges (>=32 units) they will often jump out (depends on pathnode
position). If the ledge is just barely within the safety-limit of falling damage, bots will certainly
take damage as they jump off the ledge.

Bots will never camp at spots for a longer period of time unless there is a reason for it
to do so. A bot might wait a few seconds for ammo or item to respawn, pick it up and then
continue.
In gametypes other than DM bots might stand and defend positions if needed.

When a bot gets stuck or don't know how to proceed it will either stand still by the current
pathnode or wander between two.

A bot may also get stuck by a wall. This is because the bot thinks that it is able to walk in
a straight line between two pathnodes. If a wall is too close to this path the bot might get stuck.

In fights bots will focus on the destruction of their target.
Pathnodes is then only used as "checkpoints" to keep the bot from going too far outside
the path network.
If the target goes out of sight the bot will return to the network, possibly looking
for its target for a few seconds and then keep on with it's mission.
This means that if some areas are too big/open the bot might spend more time trying to fight
opponents rather than taking the flag or control-points.


BB Drac - Unreal Tournament UED2 guide Bot pathing, Navigation network

Navigation Network

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

Bots play an important role in UT as they are the only opponents
you can play against in single 'human' player.

To spare CPU usage and give much better playability performance
bots have not been given any navigation AI.
That means that you have to tell them how to move around in
any given design and situation.
This includes how to move from one side of the level to another,
where and how to do hammer jumps or using the translocator, where to stand
when waiting for a lift and more or less every situation possible.

Luckily bots do have a certain level of AI and can cope with
some situations without much help, but still they rely on how
you as a designer lay out everything for them.

A bots behavior and level of IQ/AI also relate to what difficult
level you select for them when playing.
The biggest difference is still how fast they react, accuracy and damage.

With this tutorial I will try to explain how to create/use the navigation
network.
If you want to know more on how bots work and act read my tutorial on
 Bot AI and Basics.

In the actor browser you expand the 'NavigationPoint' for all available
bot pathing actors.

Actor | Specific
AlarmPoint | Not used in UT.
AlternatePath | Used to show bots other routes to the opponents FlagBase.
AmbushPoint | Camping spots for bots.
DefensePoint | Like AmbushPoints but teambased.
AssaultRandomizer | Used to "fool" bots to take other routes in AS levels.
BlockedPath | A navigation node that can be used to manipulate the network.
ButtonMarker | Not used in UT.
ControlPoint | A control point that is used to create DOM levels.
FlagBase | The flag used to create CTF levels.
HomeBase | Don't how this work.
InventorySpot | Automaticlly placed, do not use.
LiftCenter | Used to tell bot where to stand when using elevator.
JumpSpot | Type of LiftCenter, tell bots where to do LowG, Boots jumps.
PainPath | Don't how this work.
TranslocDest | Type of LiftCenter, tell bots where to shoot the Transloc disc.
LiftExit | Used with LifCenter as start and exit positions.
TranslocStart | Used if bots need to translocate back from a TranslocDest.
PathNode | A standard navigation node for bots.
PatrolPoint | Not used in UT.
PlayerStart | A starting position for players and bots in all gametypes.
QueenDest | Not used in UT.
SpawnPoint | Placed as a spawnpoint for thing factories.
Teleporter | Used to transport players from one postion to another.
FavoritesTeleporter | Don't how this work.
VisibleTeleporter | A teleporter but with default teleporter gfx.
Transporter | Not used in UT.
TriggerMarker | Not used in UT.
WarpZoneMarker | Automaticlly placed, do not use.

For some pathnodes I have specific tutorials.
This is AssaultRandomizer, ControlPoint, FlagBase, Teleporter
and VisibleTeleporter.
It is located in my Assault, Domination, Capture the Flag and
Teleporter tutorials.

 Building the navigation network:
To actually build the navigation network for your bots you position
nodes around the level.
The most used of all nodes is the "PathNode".
This is simply a node that tells that bot that it can walk here,
nothing else.
It looks like a golden apple when you place it in the level.

This image show you how it will look when you define paths.

Screenshot

Even though you place navigation points you need to select
"Show paths" to see how your network is connected.
To do this you press the right mouse button on the titlebar for any
viewport, select "View" and then "Show Paths".

A single pathnode is a single point in which the network is built
from. By adding nodes at strategic positions, corners, hallways, stairs
and so on, bots are able to navigate from one position to another.

As stated a "PathNode" is just a simple node. To make bots understand
tricky situations other types of nodes are used.
This includes defense points, control points, inventory spots and so on.

It is important to know that most nodes from the category "NavigationPoint"
works as a navigation node (pathnode) but with specific properties.
A good example of this is playerstarts. Its only function is to tell
the engine where it can spawn bots and players.
While playing the playerstart do not have any useful function.
However, bots will still treat this node as a pathnode and it will be
a fully functional part of the network.
This also applies to the node "InventorySpot" which is placed at all
items you place in the level, by the engine when you define paths.
This means that you do not need to place pathnodes above items, weapons and
pickups to let bots understand that they are able to walk there.
In theory you could use weapons, items and pickups placed all around the level
and not use one single pathnode and still have a fully functional network
for bots to use.

When you select define paths the engine will calculate all possible
connections between the nodes.
A connection is shown with a blue or red line between two nodes and this
is a path that bots will consider using.
To succesfully connect two nodes with each other they MUST be in visible range of
each other and not too far apart.
They should not be too close either or bots might get stuck.

Meaning that you do not place a "PathNode" at playerstarts, items, and where
other navigation nodes is placed.

The best way to place a PathNode is to place it on the "floor" in the 3D view.
To adjust the position use any of the 2D views.
The reason for this is that when you place them in the 3D view they are
placed at the most ideal height from the floor.
In some cases when PathNodes are too high up, even though you get a line to other
PathNodes, bots think they are unable to reach it.

Stairs is a bit tricky to pathnode but placing one at the bottom and one on the top
usually do the trick. If they do not connect, place one in the middle as well.
In some cases you can fix stair problems by lowering the top and middle
pathnodes a bit.

If there is a gap or edge between two pathnodes a bot might do jumps to get across.
In cases like this it is important to place nodes close to the edge
or bots might jump and fail to reach the other edge.
If the distance, across a gap, is too far the nodes might not connect with each other.

To make bots able to navigate through water you need to place the pathnodes in the water
and not above it.
Otherwise bots try to jump out of the water to reach the node and not swim.
To get bots out of the water you should place a PathNode close to the edge
and possibly another PathNode almost directly under it.
This will make the bots swim for this node and then swim upwards to reach the edge
for the other node.

 Blue or Red line:
The difference between a blue and red one doesn't really mean much
in a normal situations.
A blue line means a "good" connection while the red is a "less prefered" line.
This really dosen't mean much considering that bots take the shortest route
to its target.
However, a bot have a small term AI which is how it should proceed to the next
pathnode.
Normally a bot would go from the current node to the one in question but
if the line is red and it have another route which includes a third pathnode
but with blue lines, it could take that route instead.

In all cases the distance play the most important factor.

The situation you could end up in having trouble with this is if you
have a position in which the bot is starting from (a pathnode).
From there you can take either the left route or the right and then walk
up a platform/stair to the second floor.
(One route/side of the design is a complete mirror of the other).
If the walking distance from the starting position is the same either you take
the left passage or the right but one of them have lots of red lines the
bot will take the other passage all the time.

 Elevators / Lifts:
You use LiftExits and LiftCenter to make bots understand how to use elevators.

LiftExits is used to direct bots to where it should stand and wait for the
elevator and where to go when it arrives.
For this you need to place one liftexit beside the elevator and one
on the second floor.
The LiftCenter must be placed on the elevator and this is the spot
the bot will stand while going with the elevator.

Screenshot

A bot stands at the first LiftExit and then moves to position itself on the
LiftCenter.
When the mover arrives the bot will walk to the second LiftExit and then
continue its course.

It is perfectly legal for a mover to move in any direction and
have more than one keyframe.
The bot is more than happy riding it all the way.

One thing that is very important when creating support for elevators is
that the mover have "StandOpenTimed" and not the default "BumpOpenTimed".
Bots think that "BumpOpenTimed" is a door.
(This do not apply if you use triggers to activate the mover).

Both the LiftExit and LiftCenter have specific "LiftTag" properties which must be
set same as the mover tag which you build support for.
Simply because you need to associate the pathnodes to the correct mover,
to avoid confusing the bot.

If you use a trigger to activate the elevator, bots usually understand this
as the mover have "Trigger..." instead of "StandOpenTimed",
and will be more than happy to activate it before trying to use it.

However, lots of people have reported problems getting bots to understand
complex triggered elevators.
Keeping them as simple as possible might be a smart idea.
This problem usually only occure when bots need to use the elevator
to get down as well as up.
(Normally they would just jump down the shaft).
It can, in some cases, be fixed if you set the "LiftTrigger" property
for both the LiftExits and LiftCenters to the tag of the trigger.

If you want the elevator to stop at multiple floors you need to use "ElevatorMover"
and "ElevatorTriggers".
You also need to place a LiftExit for each floor to make bots understand where
to wait for the lift and where to walk off.
Still you only use one LiftCenter though, and it is placed on the elevator
at its base keyframe (keyframe 0 (base)).

 Hammer / Translocator jumps:
To tell bots where and how to do jumps work pretty much the same way
as elevators.
You actually use LiftExits to tell the bot where to stand and prepare
and where to "Walk off" when the jump is complete.
This means that you need to place one LiftExit on each floor/side
and one LiftCenter type where the bots should jump to.
By LiftCenter type I mean TranslocDest or JumpSpot.

As seen on the screenshot you can see that on the floor is a LiftExit,
on the second floor a JumpSpot and another LiftExit.

Screenshot

The bot will walk up to the first LiftExit, either shoot the translocator disc
or do the jump trying to hit the JumpSpot / TranslocDest, "walk off"
to the second LiftExit and then continue on its course.

There is some important differences between JumpSpots and TranslocDest.

TanslocDest is used when bots MUST use the translocator to get to the
destination.
Bots will think that they are able to get to the LiftExit they
jumped from without problem, from the TranslocDest.
If they must use the translocator to get back again you need to
replace the first LiftExit with the TranslocStart

JumpSpots only tell the bot that they are unable to get to the
destination simply by walking.
This means that a bot could use the ImpactHammer, Jumpboots, Translocator
or LowG enviroment to get to the JumpSpot.
Bots will use the best way each time.
The priority is Jumping, Translocator and then ImpactHammer.
If the bot must use the JumpBoots to make the jump the boots should
not be placed too far away.
JumpSpots have two properties you can modify and that is
bImpactJump and bAlwaysAccel.
If bImpactJump is true bots can use the ImpactHammer to complete the
jump. Otherwise they will never try it.
bAlwasyAccel means that in certain situations bots can or need to
use air control to reach the destination.

As with elevators all LiftExits and JumpSpots/TranslocDest must be
given the same tag or bots might get confused.

 Doors:
Bots will understand and use doors in most cases like "BumpOpenTimed" or
"Trigger..." activation.
When pathing you usually just put a pathnode on each side and let the bot
do the rest of the work.

In certain situations, like AS levels, bots can get stuck thinking
they can walk past the door even though the right triggers not
activated.

To fix this problem you use BlockedPaths which is explained later.

 Ambush / Defense points :
Ambush and Defense points are used to make bots camp and defend specifc
areas.
The difference of the two is that Defense points are team based
while Ambush points are not.

You use Ambush points to let bots understand that this is a good
camp spot or ambush point to attack other opponents.

Defense Points are used in the same manner but bots understand
that this point is very important to defend.
That is why Defense points have FortTag, Priority and Team properties
to let bots know when, why and where to defend.

Both Ambush and Defense points have bSniping and SightRadius.
bSniping tells the bot to stand still and shoot at the opponents instead
of going after them.
SightRadius is how far the bots should look for opponents.

Also know that both are directional and should be placed in the
direction you want bots to stand.

 BlockedPath:
Normally bots will be able to walk everywhere at any give time but
in AS levels where bots must complete certain tasks before proceeding
you need to cut off the paths and open them again at a later stage.

This is done with BlockedPaths.
They should be placed between two pathnodes and it is also important
that no path go around it or the BlockedPath is useless.

The BlockedPath is then opened when triggered by any trigger and
cannot be made to block the path again.

Most used positions are doorways and drawbridges.

 Inventory Spots, Thinking like a bot:
This node is placed by the engine above all itmes, weapons and pickups
when you rebuild the navigation network.
A bot understand and treat nodes differently.
Meaning that bots know that at inventory spots usefull items and weapons
can be collected.
This can result in bots camping by these positions to wait for the
item to respawn.
They will not wait for long though, but it is also affected by the setting
you have for the bot, regarding camping.

 Debugging the navigation network:
This is very important:
Do not expect your bots to play well the first, second and even your
third level, not matter how hard you try.
Understanding bots and why they do what they do, not picking up all itmes,
not able to use elevators, jumping into lava and so on, is something
you need to learn as you go.
The navigation network is very design and situation specific making a
tutorial explaining everything impossible.
Debugging is therefore an important part of creating the network,
especially in CTF and AS levels.

I suggest getting the MindReader mutator which is excellent when
you want to see what, why and when bot act as they do.

The best way to see how bots act is simply to play as spectator and
let one single bot roam the level to see how it handle different situations
and if it pick up all itmes.
You could do the same even if you joined in the game as a player and then
using the "Ghost" command to let you travel anywhere, but bots think
that you are part of the current game and will handle things accordingly.

If the single bot did well in your map, introduce one or two more bots and see how
they interact with each other.
Do they still pick up items and reach all parts of the level?

If bots do not pick up items when more than one bot is present it can be because
it think that the opponent is more important to engange than picking up stuff.
The reason for this might be that the area is too big.

If you have lava (or other obstacles) and bots fail to get across, they will in most
cases die.
Placing the pathnodes at slight different positions can fix these problems.

You might also see cases, pretty often actually, when bots simply ignore parts
of your level and that is even how much you try to lure them there.
Then I must ask... Why should the bot go there?
If it is a dead-end part of the level and nothing to get, then it is pretty simple.
If you have items there, what use do the bot have of it?
If it is another enforcer I would say the bot would barely consider it.
Bots calculate the route using priorites and how much time it must use to get there.
Good levels should not have dead-ends (except for assault) and the bot should
not need to sacrifice time and health to get items.
The navigation network do not tell the bot that it MUST go there but only that
it is possible.

Stairs/ramps should pose no real challange.
In some cases when the stair/ramp is too steep bots can refuse to walk up and
down.
Adjusting the height (lowering) of the pathnodes and possibly adding one or
two, placed in the middle can fix that.

In water bots do not care of the amount of air they have.
If you path the underwater too complex and even have a too open area with
bodies of water bots might spend lots of time underwater fighting and swimming.
In the end they just drown.
If this is the case it is important that you do not make them want to swim around
by having too much of the "good" stuff placed there.

Believe it or not but MedPacks will often become a really high priority when
bots badly hurt.
If you place them at too difficult places bots might suicide themself trying to get them.
This includes underwater problems.

A bot might get "stuck" in water or just tramp around at the surface or even underwater.
Often this is because the bot either cannot reach the pathnode or it cannot "see" anyone
close enough.

The get stuck problem can also occure on land when bots seem to be trying to walk through
walls/doors.
If they get stuck at walls it means that the connection between two pathnodes is
too close the the wall.
Moving one or both a bit out from the wall can fix this.
If they do it with doors it means that they think the doors will open and when they
don't, bots get stuck.
Setting the correct opening procedure for the door or use "BlockedPath" might
be the correct solution.

Sometimes bots do not use the elevator or other jumpspots at all.
Deleting the pathnodes and place fresh new ones will most likely fix the problem.
(This includes the flagbase in CTF levels if bots ignore the flag).

I will add more stuff to Debugging later on it is simply too large to be covered
in one sweep. If you have ideas, questions or suggestions mail me.


3DS Max Terrain For UEd2

Bot Path Noding 101

By: Adam ‘Muad'dib’ Stiles

http://www.planetunreal.com/muad

muad@planetunreal.com

PRE-REQUISITES:
Basic knowledge of UnrealEd
An amount of time and patience

Bot pathnoding. A lot of mappers cringe at those words, but they're really not all that terrifying if you know the basics first. If you're new to mapping or even if you're from the old-school quake community, bot path noding may be an entirely new concept. Gone are the days when a mapper could build a nice map intended for living breathing people to populate and play within - now, with the advent of Unreal Tournament (as well as Quake 3) bots are becoming a standard feature and mappers have to take good bot action into account as well. First lets discuss a bit about bots, as well as just what pathnoding is.

Bots are the generic term for a computer controlled opponent. In a way, you could think of every computer opponent as a "bot" of sorts. Ever play a fighting game like Mortal Kombat (tm), or perhaps Street Fighter (tm) ? Well, if you play the single player of those games you are, in effect, playing against bots. Bots can be essentially boiled down to lines of computer code being executed on the machine. Now, as such, bots have well defined limitations. They are NOT human opponents, and will undoubtedly have certain predictabilities.

Within the Unreal engine bots are controllable and definable, to a degree, by the map author. This control is achieved through a process called path noding. Path noding is, essentially, what it sounds like - it is creating a pathway/group of pathways or a network, of "nodes" or pre-defined positions that the bots will use to navigate the map, find powerups or weapons, as well as locate elevators, lifts, teleporters and the like.

Now the question is "what exactly is a node?" Good question. The definition of a "node" can vary within the Unreal Tournament realm. Basic definition: A node is a 3D position in your map that the bots in Unreal can travel to. However, a node can be much more than just a point that a bot goes to. A node can also contain special information about the location it is placed at. There are special nodes that tell the bot that a weapon, for instance, is located there, or that an elevator is located there, or even a place where the bot is to make a leap or a jump.

So now that you have a basic definition of this path noding business, lets get to applying it to your level so you can get bots running around your map!

Basic path noding isn't really that hard, however as a UT map author a main objective of yours should be attempting to path node well so that bots play better or more like a *human* would. THAT is the difficult part. Path noding is an art form, just as mapping is, so treat it as such!

First let's figure out how to place a pathnode in the map. First open up your Classes Browser and expand NavigationPoint (makes sense doesn't it?) Locate the sub item called "PathNode". There you go. Go about adding a path node to your map the same way you'd add any other actor (like a light for instance) with the usual right-click on the 3d view and choose "place PathNode here"

It can't be that easy can it? Well, yes and no. Like I said, you want to place your path nodes in a way to simulate human like movement with the bots. So place your path nodes in logical places that you'd want the bot to travel to - think about it - put them where YOU would go if you were to play the map.

A logical rule of thumb with path noding is to at the very LEAST place a path node at every intersection. Also path nodes work from line of sight - that is, if a path node can't be "seen" from the location of another path node, then no path will be made between the two (result: the bots won't run in between those two points). You also don't want to cram path nodes right next to each other and at the same time you don't want them too far away. What's too far away? Judgement call really - we'll get into that later down when we actually build the paths themselves...

Now I said earlier that there were special pathnodes to tell a bot where weapons and items were. These path nodes are actually *the items and weapons themselves*. So if you plop a mini gun down somewhere and want a bot to get to it, just add a pathnode somewhere around (but not to close) to the gun. The gun itself will act like a pathnode and the bot will then see it as a weapon. Ditto with things like ammo, health packs, armor, shields, invisibility and TELEPORTERS (well the right kind anyway). When using a teleporter that the bots will use you'll want to go to your classes browser, expand NavigationPoint, then expand Teleporter and find and use the class called "VisibleTeleporter" we'll get into that in a second pathnoding tutorial. The "PlayerStarts" that you place around your map will also act as path nodes.

Ok so you should now be able to plop down path nodes around your map making sure that the pathnodes you want the bots to travel between can "see" each other and with the nodes not too far apart or close together. How to tell if the distance is right? Well, to tell that you need information on the paths themselves which first need to be "built" between those nodes you plopped down. Press F8 to bring up the Rebuilder Dialogue Box. You should be familiar with this dialog, but may have wondered when you clicked on that "Lighting" tab, just what that "Paths Define" button does. Got any ideas on it now? :) Click it to actually generate the paths between those PathNodes you created. UnrealEd will chug for a while and finally finish.

Now you'll probably want to actually see the paths to get an idea of how you're bots are going to do. On your 3D view port, click the "View" menu item and choose "Show Paths" - you should now see a nice network of blue and red lines all over your map drawn in between your path nodes. REMEMBER: whenever you change the position of any of your pathnodes, weapons, items, or anything that can ACT like a pathnode you need to click that "Paths Define" button again to rebuild the paths. Just like when you rebuild your map!

Great - lots of red and blue lines. What are the red and blue colors supposed to signify? Well, these are the paths that the bots CAN (but not always necessarily) take. BLUE paths are paths that are attractive to the bots. These are the paths that the bots are most likely to take. Red paths are paths that a bot will take, but probably only if it has to for some reason. In other words, they're paths that are unattractive to the bots. So when you rebuild your paths, remember, RED is ok, but BLUE is better!

If you need to move your path nodes around, go ahead, but be sure to rebuild those paths with "paths define" before saving your map! By moving your path nodes around, you can sometimes get the red lines to change to blue. The red lines sometimes mean that the nodes are too far apart or too close together. MOST LIKELY, though, a red line means that there's an easier path to take to get to the desired location. After this is all done give your map a test run with some bots! Remember to place plenty of PlayerStart actors in your map to accommodate the number of bots you want to use. In short, it's not a good idea to have 3 PlayerStarts in your map and then decide you want to play with 6 bots. You'll get telefragging happening right out of the gate (two people will attempt to start or spawn into the game in the same position). Name your map with the appropriate prefix (like DM- for a deathmatch, CTF- for capture the flag, etc) so it will be available in the in-game map selection screen.

Most of all HAVE PATIENCE with path noding. It's easy enough to start, but takes practice to get good results with. Like I said - it's an artform! We'll discuss advanced topics like elevators, doors, teleporters, and even some CTF specific path noding techniques in another tutorial.


3DS Max Terrain For UEd2

Bot Path Noding 102

By: Adam ‘Muad'dib’ Stiles

http://www.planetunreal.com/muad

muad@planetunreal.com

PRE-REQUISITES:

Basic knowledge of UnrealEd.
Creating basic movers suitable for doors and elevators.
Gone through the "Bot Path Noding 101" tutorial.

If you went through my first Bot Path Noding tutorial, then you know that when I left off I mentioned covering some more "advanced" pathing topics such as doors, elevators, and teleporters - I'll be covering CTF related bot issues in a third pathing tutorial. Now let's get down to it!

DOORS:

First stop - the easiest of the above, the doors. Doors are pretty straight forward actually, although some folks can run into problems with them depending on how they have their doors setup. First things first, though, you're going to need a map with a door. Now for most deathmatch type levels a sliding door is usually appropriate. Whether it slides up or down isn't the issue - the issue is that the door needs to open fast enough that when a bot wants to run through it, they don't get caught on it. Right? So let's set up a door that would be appropriate for this:

First create the mover for your door (you should already know how to do this - if not, go through the tutorials at http://unreal.gamedesign.net/). We want just a generic mover in this case - no fancy subclasses, just a simple Brush->Mover with most of the default properties will do fine. You DO need to check the Mover->MoveTime though. This is the amount of time it takes for the mover to go from point A to point B. In this case how fast our door will open - we want it relatively fast so the bots don't get hung up on slow doors so make it 0.5 for now (you can edit this to your tastes later).

Now place a PathNode actor on either side of the door. Use the "Define Paths" button in the rebuilder dialogue to generate your paths, and then choose View->ShowPaths under your 3D view window. If all goes well, you should have a blue line going between your PathNodes and RIGHT THROUGH the door. Now fire up UT and give it a go!

Rotating doors (e.g. a door on a hinge) is a similar set up. You do, however, want to be certain that the PathNodes you place don't end up in the path of the door. Make sure they are outside the swing radius of the door.

ELEVATORS or LIFTS:

Oh boy. Elevators, otherwise known as lifts - this is a common map item now a days and if you're not used to pathnoding at all, elevators can, well, be a pain in the arse to setup. Here's how:

Of course, first, you need an elevator. Same setup as a door - just a generic Brush->Mover with most of the default properties. However, this time you NEED to set the Object->InitialState to be "StandOpenTimed". This means that the mover won't move unless someone is standing on it. It'd suck to have an elevator which went flying up at a mere touch (before you managed a foothold on it that is). The Mover->MoveTime property is subjective here. A smaller number indicates a faster move speed in general so set it up how you like.

Now getting a bot to use this thing is pretty odd. For our example, lets assume that you have an elevator that starts out on bottom, moves to a "top" location when stepped on, and then goes back down after a period of time. In order to get a bot to use an elevator (or a "lift") there are some special actors (that will act as pathnodes if you remember the last pathing tutorial) that tell the bots where to get on the elevator, where the elevator is, and where to get off of the elevator at.

The actors are called LiftCenter and LiftExit and both can be found in the Classes browser under NavigationPoint. You'll need 1 LiftCenter and 2 LiftExits to get bots using your elevator. The two tricks is to tie them to your elevator somehow and place them in the map correctly. So let's do it.

First off - enter the properties for your elevator mover. Edit the Events->Tag property and give it some unique name to identify the lift/elevator. In our example lets use "lift1" (no quotes). Great now we have a name for our elevator which will be a convenient way to tie our LiftCenter and LiftExits to it. Now lets go ahead and set those up.

Create a LiftCenter actor and place it just over the lift/mover - not too close to the surface of it, but slightly above it - about the same distance a pathnode would be off the ground. Edit it's properties and give it a LiftCenter->LiftTag of "lift1" - no quotes of course (this tells the engine which lift this center is for).

Now create a LiftExit just in front of the lift on the ground - the bot will stand at this spot just before stepping onto the lift - think of it as an entrance point to the lift. Edit it's properties and give it a LiftExit->LiftTag of "lift1" (sound familiar yet?).

Create your second LiftExit at the top of where the lift will go and place it over the surface that the bot will step out onto after the lift stops at the top. This will be the real "exit" point of the lift. Edit it's properties and give it a LiftExit->LiftTag of "lift1" (bet you guessed that tho).

Now do the "Define Paths" thing, show the paths and make sure that you get lines (preferrably blue of course) between the LiftExits and the LiftCenter. The LiftExits will act as typical PathNodes (ie the Define Paths will generate paths between them and a regular PathNode) so use some PathNodes to guide your bots to the bottom LiftExit so they'll know how to get to your lift!

TELEPORTERS:

With UT there's an easy (easier anyway) way of getting teleporters and bots to coexist peacefully - if you check in your classes browser, you should be able to find a NavigationPoint->Teleporter->VisibleTeleporter. Plopping one of these down in your map will create that neat little blue and white swirly line teleporter that you see all over various UT maps. This teleporter will act as a PathNode. In other words, you can place some regular PathNode actors around it to guide bots to it and the Paths Define function will generate paths between the teleporter and the nodes. So you know how to get one in a map, but the problem now is telling the thing where to teleport a player to!

There are a couple of options here. Depends on how you want to exit. First we'll cover what to do if you want to come out of the teleporter and NOT be able to teleport back (ie you enter teleporter, and when you exit there's no teleporter around) Second, is being able to teleport back and forth between two teleporters.

First Option: Not being able to teleport back. This, DOES have it's uses - check my map DM-Overseer for an example of this. There are two teleporters on the top tier - both of which teleport you to the bottom tier. But you can't teleport back - one way trip, and the only way back up is to climb it! So lets set this up.

Plop down a VisibleTeleporter as described above, edit it's properties and give it a Teleporter->URL of "teletarg1" (no quotes). Ok now we need to create this "teletarg1" thing.

This teletarg thing is actually the generic teleporter. Create a NavigationPoint->Teleporter where ever you want to be teleported to. Notice it's also got a Teleporter->URL property. Leave it BLANK. But DO give it an Events->Tag of "teletarg1" (no quotes). Generate your paths as normal by now and you should have a functional teleporter that bots will use.

Second Option: Being able to teleport back. Easy. Create two VisibleTeleporters. Edit their properties separately - give the first one an Events->Tag of "tele1" and a Teleporter->URL of "tele2". Now give the SECOND one an Events->Tag of "tele2" and a Teleporter->URL of "tele1". I.e. they're pointing at each other which is exactly what you want! Now generate your paths and test run it!

CONCLUSION:

This, along with the first pathing tutorial should give you a few rounded tricks to use in your own UT maps to make them more interesting for people to play. As ALWAYS take your time with pathnoding - it can often be a tedious process to get the bot behaviour just like you want it (and in some cases your desires may even be outside the realms of the engines limits ;) But good pathnoding can really make or break a level.

In the next pathing tutorial we'll cover some CTF related pathnoding issues (as well as a few quirks that I've stumbled across and subsequently managed to solve). So stay tuned!


3DS Max Terrain For UEd2

Bot Path Noding 201

By: Adam ‘Muad'dib’ Stiles

http://www.planetunreal.com/muad

muad@planetunreal.com

PRE-REQUISITES:
Understanding of basic path-noding. Check my bot-noding tutorials.
The typical UnrealEd (1 or 2) knowledge.

Ok by now you should at least have a solid understanding of UnrealEd so I'm going to assume that you know how to edit the properties of actors and brushes and such :)

Capture the Flag bot noding is a little bit different than typical deathmatch bot noding, but is rooted in the same principles. You want a nice network of nodes for the bots to follow, but don't want the network excessive. You want the bots to behave well.

This works great for regular deathmatch, but capture the flag has a few extras you need to pay attention to: you typically want bots to use different routes to the flags, you want bots to be able to defend the base, and of course you want bots to be able to capture the darned flag!

A list of pathing related actors a CTF level NEEDS to have:

  • PlayerStart

  • PathNode

  • FlagBase

A list of pathing related actors a CTF level SHOULD have:

  • PlayerStart

  • PathNode

  • FlagBase

  • DefensePoint

  • AlternatePath

All of these items, by the way, can be found in UnrealEd within the Actor browser under "NavigationPoint". Let's go over what each one does and what properties we need to look at:

  1. PlayerStart:

    If you dunno what this is then you really shouldn't be reading this :) This is a spawn point for a player.

    Properties:

    • PlayerStart->TeamNumber : used to set which team color will be able to spawn here. 0 is red, 1 is blue.

  2. PathNode:

    This is the typical building block of a path system. If you've done deathmatch pathing before you'll know how to use these, if not then check my other pathing tutorials.

  3. FlagBase:

    This is the actual flag. You'll notice that if you place one of these down it plops down with only one flag color visible. Not to worry.

    Properties:

    • FlagBase -> Team : Set this to the number of the team you want this flag to belong to. 0 is red, 1 is blue. This changes the color of the flag IN GAME, but NOT in the editor - just make sure the team number is set correctly ;)

  4. DefensePoint:

    Located under NavigationPoint->AmbushPoint->DefensePoint. If you tell your teammates to "defend the base" in a CTF game, the bots will go to these points to defend.

    Properties:

    • AmbushPoint->bSniping : Set this to true if you wish the bot to use sniping skills at this defense point.

    • DefensePoint->Team : the team to which this defense point belongs. 0 is red, 1 is blue.

    • DefensePoint->Priority : used to set the likelihood that a bot will pick this defense point to defend from.

  5. AlternatePath:

    A tricky one this is. This is used to give the bots a way of recognizing an alternate path to the flag.

    Properties:

    • AlternatePath->Team : this tells the bots which teams flag this is an alternate path to. ie if red bots are supposed to use this AlternatePath to get to the blue flag you'd set the team to be blue. 0 is red, 1 is blue.

    • AlternatePath->SelectionWeight : used to set the likelihood that a bot will use this path to get to the enemy flag. Very useful if you have several paths to get to the enemy flag (which you should).

Ok so now we know what they are and we know what they can do, but how do we effectively use them? Here's the method I typically use for completely path noding a CTF level. This is NOT the only way to do it, but I find it an effective way of going about it.

  1. Place player starts:

    I know this one really should go without saying, but you really need to do this first. Particularly with CTF maps as you need to pay attention to the Team property and make sure the numbers are set correctly. You don't want red team members spawning in front of (or inside of for that matter) the blue base :)

  2. Place weapons and items:

    This should probably come next as it's an extremely important part of either deathmatch or CTF pathing. Weapon and item placement can make or break a level. You will typically want to put weapons and maybe weak armor in the vicinity of a spawn point. Nothing worse than spawning and getting blitzed because you didn't have a decent weapon to fight with.

    You'll probably want to put strong armors and items (like the shield belt, UDamage and Redeemer) farther away to make players work for them.

    This part is also tweakable later, but you should start thinking about good item and weapon placement at this stage.

  3. Flagbase and defensepoints:

    Odds are you knew where you wanted the flags to go when you started building the map. Go ahead and put them down if you haven't done so already. Also start finding good spots to defend the base from, put down some DefensePoints and make sure you have the Team attributes set correctly!

    The defense points should probably be placed at some choke points of the map and/or near the flag itself. Also remember that you can set DefensePoints to be sniping points so keep that in mind when putting them in your map.

  4. Pathnodes:

    Now you ought to start putting down your network of pathnodes just as you would in a deathmatch map. Placement of the items in sections 1, 2, and 3 above will help to guide you in your generic pathnode placement.

    Always keep in mind, though, that you're pathing for TWO teams here. There should be decent pathing for both teams and make sure that there are solid paths between the flags!!

  5. AlternatePaths:

    These things are tricky at best. Here's the way I handle them tho. Typical CTF levels are somewhat symmetrical in nature (ie there's a definite "halfway" point between the flags). You'll want to put an AlternatePath, for the blue team for example, on the half of the map that the blue team resides on and it needs to be part of the path that the bot should take. ie if you have a road that leads to the blue base, put the AlternatePath on the road, on the half of the map that the blue team resides.

    You can use MULTIPLE AlternatePaths and you're encouraged to do so. In my map "CityOfSynn" you can open it up in UnrealEd and see where I placed AlternatePaths. I put them at obvious "starting" points of a possible path to the flag on the side of the map that the base the path was to resided on. Yes these things can be tricky to get the hang of so if it doesn't work the first time through - don't feel bad :)

    If a bot doesn't seem to be using an AlternatePath and you're just *sure* you have it in a correct physical location, don't forget that you can fiddle with the SelectionWeight property to adjust how much a bot "likes" this AlternatePath.

That pretty much covers the basics for a CTF level. I've included here some answers to FAQ's typically posed by people building a CTF level and having troubles with it.

Q: My bots won't capture the damned flag no matter what I do!

A: ALWAYS make sure that the FlagBase has it's pole SUNK into the floor. Ie, it shouldn't be "hovering" above the ground, but should be firmly planted in it. Whether this is a bug kind of thing in the AI, I dunno, but I've seen this problem in action before and it does help in some cases.

Q: Ok I planted the flag. The bots still aren't going for it.

A: Make sure the path to the flag isn't very obstructed. Remember, bots dislike roaming through tight places (like small doorways/hallways) and hate lava/slime/damage areas. Also remember that a bot chooses the *shortest* route to a flag it can find. And please please please for the love of God ALWAYS do a "Paths Define" before saving your map! :)

Q: I've got people of team blue spawning in the red players spawn points.

A: Double check the Team attribute of the PlayerStarts. After that, do a "Paths Define" to rebuild the pathing.

Q: I've got really weird stuff going on with my map. Where can I get more help?

A: Goto http://unreal.gamedesign.net/ - you'll have to sign up for an account (absolutely free and no nagging email spam either) to be able to post there, but the people are friendly and knowledgable on Unreal editing. I keep spouting this URL all over my pages - believe me it's an *invaluable* resource. Go there and ask questions - someone is very very likely to answer. (to my recollection, I've not seen a message get posted there yet that someone hasn't at least posted a reply to)


Basic map submission

Comprehensive Bot Path Basics

By: Deathbliss

Deathbliss

Comprehensive Bot Pathing Basics:

Make sure you know the basics of UED 2.0 before you try to follow this tutorial - OK? I tried to keep everything at beginner level but there are a few things I didn't go to great lengths to explain. The purpose of this lesson is to teach you exactly how to path the various parts of a level, from water to lifts, and getting the bots to Sniper - I cover it all here. This all came about when a review I recently did left me with the desire to give mappers a comprehensive guide on this subject. I'll tell you this now, just about every well known mapper will say it's easy to botpath, but in the end they don't really know what they are saying. Some of the best pathing I have seen is in levels by some of the least known mappers. I'll tell you what I have learned so far and the basics and hopefully from there you'll be able to do whatever you want to do with the bots.

NOTE: Two things to remember when pathing:

1. Less is best (the fewer PATHNODES you use the better).
2. ALWAYS COMPLETELY path your levels.

Pathing as I will be referring to it is the process of adding pathnodes to your level. Open up UED 2.0 and the ACTOR CLASSES BROWSER:

You're going to learn all about the PATHNODE as you go through this lesson. I guess we'll need a room so we can learn a few things. First off RE-SIZE THE GRID to 2, then open up the CUBE BUILDER and make a cube to H=256xW=1024xB=1024. SUBTRACT it after picking a texture you like. One you have the room looking the way you want go back into the ACTOR CLASSES BROWSER and find PATHNODE once again. Place one of these in each corner, in either the SIDE VIEW or the FRONT VIEW and make sure each PATHNODE is 2 darker gray grids above the floor - aligned on the cross right above the second darker gray grid. These should never be more than 4 darker gray units above the floor (chest height) and they should never be below 2 grids from the surface they are above. OK, now place a PLAYER START in the middle, and slop a light near the ceiling while you're at it, then REBUILD and SAVE INCREMENTALLY. Now in the TOP VIEW RIGHT CLICK on TOP and go to VIEW/SHOW PATHS. Click on that so a little checkmark appears next to it. Here's what you should see (minus the lights):

OK, what you are seeing here is the path the bots will take around the room. The BLUE PATHS are the most desirable to a bot - these are the paths the bots prefer to take. RED PATHS are undesirable and the bots will rarely use them or they will only use them if there is something they want at the end of the path. Now, to make a point I want you to start up Unreal Tournament, and under PLAYER SETUP I want you to check PLAY AS SPECTATOR. This is how you will watch the bots and get into their head. Select just 1 bot on NOVICE skill and start a session. You'll see that the bot just hangs around the PLAYER START as if it's fearful of something. To see what the bot is thinking press the TILDE KEY to open up the CONSOLE and type VERBOSE. The bots thoughts are seen clearly on the screen. You may want to assign this command to a key for easier access. What we have established here is that the PATHNODES are not in and of themselves what a bot needs to move around a level. The pathnodes are more like the reflecting borders in the center of a road. ITEMS such as WEAPONS, HEALTH, and POWERUPS are what a bot is after - they are the place the road takes you and what will make a bot run about a level. To demonstrate this fact select all the PATHNODES by RIGHT CLICKING on one and then SELECT ALL PATHNODE. DELETE them but leave the PLAYER START. Now in each corner place an object - in one corner a WEAPON, in another some AMMO for it, then a MEDBOX, and finally one more thing of AMMO (for a total of 2). REBUILD, SAVE INCREMENTALLY and you'll see the same pattern as before. OK, a note before we go to see what the bot does. I work with the grid RE-SIZED to 2, and I place WEAPONS precisely 1 darker gray grid unit above the floor. This is so it's not floating way above your head and looking dumb, or spinning around in the floor and looking worse. Things like AMMO and HEALTH (the MEDBOX) are all placed one small unit above the floor (there are 8 of these per darker gray grid unit 8x2=16). I suggest you position yours accordingly. In addition I place things about 1 or 2 darker gray grids away from the nearby wall(s) or floor(s).

NOTE: All WEAPONS should be placed no more more than 4 darker gray grid units above the floor with the grid RE-SIZED to 2. PLAYER STARTS, HEALTH, AMMO, etc. should be placed one small unit above the floor. ALL ITEMS should be placed with a little distance between them and any nearby walls, floors, ceilings, etc. NOTHING SHOULD BE PLACE ABOVE 4 DARKER GRAY GRID UNITS (this is 16x4 which equals 64 - between 48-64 is chest height for all players) OR BELOW 2 DARKER GRAY GRID UNITS!!!

If you adjusted anything REBUILD and SAVE INCREMENTALLY again, then PLAY the level.

You should see something like the above pic. The bots will run right from the PLAYER START, collect all it needs at the moment, and then return to the PLAYER START. It'll keep doing this until it has reached the maximum ammo count for the weapon it has. If you want to see them get the HEALTH, merely add another player start somewhere between the INVENTORY SPOTS (where the WEAPONRY, AMMO, and HEALTH is according to the bots mind). Start up a round of two bots and you'll see them duke it out. One of them will eventually retreat to get some HEALTH. So from this we determine the following:

1. PATHNODES are merely guides to ITEMS.
2. Bots will only get what they need, and they will continue to collect until an enemy comes into range.
3. A level should have as many BLUE PATHS as possible.

OK, now for a few more complicated things. I need you to build a walkway around your level about halfway up. Leave a space H=16xW=128xB=128 opened for a lift, and make each platform 128 wide. You should have something like the following:

At this point once you have done that you should have two tiers - one is a walkway above the other one. Make a lift to fit in the space and texture as you like. When you set it up remember that bots will only understand lifts that are under OBJECT/STAND OPEN TIMED or the various trigger timed types. They do not apparently understand the various bump timed types. Oh, and yeah, the level used for this demonstration will be downloadable. One you've placed your lift in the proper place and you have it set up the way you like REBUILD, and SAVE INCREMENTALLY. Now open up the ACTOR CLASSES BROWSER once again and find NAVIGATION POINT. Place a LIFT EXIT 4 darker gray grids away from the lift on the first tier. On the next tier place one also 4 darker gray grid units to the right side of where the lift will stop. Back on the ground floor place a LIFT CENTER in the middle of the lift. Make sure all of these are 2 darker gray grid units above the ground:

Now select both the LIFT EXITS and under LIFT EXIT/LIFT TAG put bpl (as shown in lowercase - stands for bot pathing lift). then select the LIFT CENTER and under LIFT CENTER/LIFT TAG place bpl there as well. Finally RIGHT CLICK on the mover and under EVENTS/TAG place bpl.

NOTE: When pathing a lift, or when using any combination of LIFT EXIT with a LIFT CENTER (and any type of these) make sure the LIFT EXIT or CENTER TAG(S) all match the tag of the mover or goal. For example - if you want a bot to jump off a cliff into some water have a LIFT EXIT where the bot will jump off from, a LIFT CENTER out away from the ledge level with the LIFT EXIT for the bot to aim for, and either a PATHNODE or an ITEM with its EVENTS/TAG set to the same name as the LIFT CENTER(S) and LIFT EXIT(S) LIFT TAG(S). ALL LIFT TAGS MUST MATCH!!! Also remember that the LIFT EXIT or LIFT CENTERS EVENT/TAG WILL NOT WORK and it IS DIFFERENT from the LIFT EXIT or LIFT CENTERS LIFT TAG which will work.

Now as you can partially see I have placed some ARMOR2 to the other side of where the lift stops on tier 2. This is also for a demonstration - so I advise you to follow along. Since the ARMOR2 is in one corner on tier 2 I'm placing PATHNODES at the other three. Almost straight across from the lift I have placed a SNIPER RIFLE and some AMMO (BULLET BOXESx2). After you've got your level all set up REBUILD, SAVE INCREMENTALLY, and PLAY the level. You'll see the bot either go around the room or head straight for the lift, the ARMOR2, and then the SNIPER RIFLE. The PATHNODES help the bot to find the way to the SNIPER RIFLE, and all the paths so far are blue. You probably also noticed the bot will use the LIFT EXIT to get off, and then it will turn around and grab the ARMOR2. See if placing bpl in the EVENT/TAG of the ARMOR2 helps. Here's a pic of the current path network:

Well let's jazz things up a bit shall we? I'm removing the MINIGUN and MINI AMMO I used on the first tier in the corners. I'm instead under the walkway where the SNIPER RIFLE is adding 2 PLAYER STARTS in the corners, with a MEDBOX per opposite corner so we can get some one on one action going. I encourage you to do this, and then after you have REBUILT the level and SAVED INCREMENTALLY I encourage you to join the bots. I'm going to add some trim to my level and a little protection to the Sniper Point. We can then go into using AMBUSH POINTS. Here's what I have designed so far:

As you can see I have a ledge for the Sniper to stand behind, and this overlooks the lift so it is a very strategic spot. OK how high would this ledge have to be? Anyone? If you said 48 (actually between 48-64) you are correct. Once you have your ledge designed (mine is a vertice edited cylinder - you may be more basic of you so desire) go into NAVIGATION POINT and find AMBUSH POINT. Select it and add it behind the wall. Make the arrow point out toward the open area by rotating it in theTOP VIEW. To rotate all you have to do is highlight it, PRESS and HOLD CTRL, and then drag with the LEFT MOUSE BUTTON also pressed and held. Once that's done make sure it's 2 darker gray grids above the ground. Then RIGHT CLICK on it, go to AMBUSH POINT, and set BSNIPING to TRUE. This tells the bots that when they get there they can hide behind that ledge and pick opponents off. It's more useful in a team game such as a CTF or DOM match, but will also work here. After REBUILDING and SAVING INCREMENTALLY if you check SHOW PATHS again (I expect you've been unchecking it so you can align things easier) you'll see we now have a RED PATH. Not so bad considering the BLUE PATH leading right to the same area - nothing to worry about. Try it out and watch those bots have at it!

So you want your bots to navigate water huh? Make a cube H=128xW=256xB=256. Subtract this from the middle of the floor. Give it a water sheet you like and add a WATER ZONE INFO inside under the sheet. I decided since the bottom of this pool would be a high risk area that I would add a powerup. So I chose the DAMAGE AMPLIFIER, and I added it right to the bottom of the pool in the middle. Right above this and also above the water sheet place a LIFT CENTER. Then in the middle of each side place a LIFT EXIT. Put bpw under all the LIFT EXIT LIFT TAGS, and the same for the LIFT CENTER LIFT TAG and the EVENT/TAG of the powerup you chose. Here is what you should have:

The LIFT CENTER is in the middle above the water sheet and the powerup, and the LIFT EXITS are on each side. The bots should easily navigate your water now. All that's left at this point is teaching you how to make the bots TRANSLOCATE, some advanced Sniper and DEFENSE techniques, and a few other things that I think I will save for a later lesson since this one has become so long. Hopefully at this point you know how to path pretty much anything you want, from lifts to water, and maybe some misunderstandings have been cleared up as well. As always you can use the link at the bottom left of this page to e-mail me if you have further questions. Good job everyone!


Pathnoding Unreal Levels for the Unreal Bots

by: Randar
mimpchnk@uswest.net

In a very real sense, the Unreal Bots are ONLY as good as the levels designed for them. In other words, for the Bots to play at their optimal best, the Unreal levels must be carefully created for them. While there are many good deathmatch levels out there for human play, there are unfortunately too few that are great for Bot play. (I have seen some levels that can NOT be adequately pathed for the Bots!) This tutorial will attempt to help the level designers design levels that will make the Unreal Bots and the Bot loving community happy.

WHERE DO YOU BEGIN?

First, design a level with the Bots in mind. This means that you must know the limitations of the Unreal Bots. (Yes, they DO have their limitations!) The Bots do NOT like levels with too much water, lava, slime, or acid in them. Even with good pathing, they either will avoid these areas altogether, or you will always find them jumping in and choking it down. Another little problem with the Bots is they apparently cannot use all of the items (i.e., jump boots, force field, etc.) that the human players might find in their inventory.

All in all, the best levels for the Bots are those that are designed with an elegant simplicity. If a level is too complicated or has a lot of tricks and traps, it will probably present problems for the Bots. Now, while it is tempting to design a killer level with all kinds of bells and whistles, the best levels for deathmatch (whether for humans or for Bots) are those levels that tend to be the simplest in design. Save all of the unique and unusual effects for the single player levels. For the deathmatch levels, the best ones are those that are fast and efficient—given to the one and only goal of "kill or be killed." Of course this does not mean that a good deathmatch level must be boring. Use textures that work well together and support the theme of your creation. But keep the "eye candy" to a minimum. Levels that contain a lot of special effects (i.e., lighting, fog, etc.) will really slow down when a Bot or two are added to them.

THEN WHAT?

After a level has been completely designed, pathnode the level for the Unreal Bots. In the "Browse" Menu at the right hand side of the Unreal Editor choose "Classes." Under Actor Classes choose "NavigationPoint." Under NavigationPoint you will be using "PathNode" to path the level for the Bots. And, so the Bots can use the elevators, you will also be using "LiftExit" and "LiftCenter." In one of the Map View screens (Mode—Textures; View—Show Moving Brushes; Actors—Full Actor View) choose the view that allows you the first person perspective so that you can move through the level.

THE PATHNODES

Under Classes, NavigationPoint, choose and highlight "PathNode." Place the pathnodes in the level by pointing to the location on the floor where you want the node to go, then right click the mouse and choose "Add PathNode Here." The pathnode will appear. (It is a Golden Apple.) Continue pathing the level choosing the best possible route for the Bots. All pathnodes should be placed at key points—next to weapons or items. Each pathnode should be visible to the next pathnode which is in sight of the next node, and so on. (In other words, do not separate the nodes by too great a distance. But, don"t place them too close together either.) On stairs, place one pathnode on the floor at the middle of the base of the stairs, and place the next node on the floor at the middle of the top of the stairs. (In other words, you should only have two nodes per flight of stairs: one at the top, and one at the bottom. Try not to put any nodes in the middle of the flight of stairs.) The two nodes should be visible to each other. If there is a landing (that changes the direction of the stairs) place a node on that landing, and, of course, another at the top of the stairs. (Do NOT place a node on every step! Of course spiral staircases present a unique pathing challenge—just do the best you can, with as few pathnodes as possible.) Continue to path the level until you have left a trail of "golden apples" throughout the entire level.

    PATHING TIP: Some areas are very difficult to path because they are too small for the Actor. (You will get a message saying: "Actor does not fit here.") Difficult areas would include ledges that are too narrow, rooms or halls that are too small, etc. One work-around is to place items in these areas, if you know that the player actually can go there. Then place a pathnode as close to this trouble spot as possible. The pathnodes will usually link to the items in and through the problem area when you do a "Path Define." But, the best work-around is this: You can MOVE any pathnode or item to exactly where you want it (moving it in any direction; left, right, front, back, up or down) by selecting it, after you have placed it, and using a combination of the CTRL key and the left or right or left-right mouse buttons, for precise placement. (You can also DUPLICATE an existing pathnode by right-clicking on it and choosing "Duplicate.") This means that you can move a pathnode into an area that gives you an "Actor does not fit here" message. So, you can put pathnodes on narrow ledges, in difficult areas, spiral staircases, etc. You can do the same thing for the elevator nodes as well. One more thing. If you use any portals or teleports in the level, make sure that you place a pathnode just outside the portal, and put a pathnode inside the portal chamber as well. You may have to move the pathnode (as described above) to place it in the best center position.

    PATHING TIP: Every once in a while, you will come across a specific area that almost defies pathing. What do you do? Well, here is a little trick that really works: use the "LiftExit" and "LiftCenter" nodes! (Just be sure and give both of their LiftTags the same name.) You read that correctly. You can use the elevator nodes to get the Bots to jump or drop to difficult areas that may not easily link when you do a "Path Define." You can even use the elevator nodes to help the Bots get into and out of water more easily. Another interesting use of the liftnodes is in a low gravity room. You can actually get the Bots to jump UP to higher areas to retrieve items. (In normal gravity, they would only jump to the same level or drop down to the next lift node. But, jumping in low gravity gets the Bots to jump higher than they even "expected.") Be creative and find other ways to use these special nodes to move the Bots into and out of unusual areas! One other thing that you can try is to increase the "desirability" of any item that the Bots can get and use. Every item has a "Properties Sheet." In it you will find the "maxdesirability" field. Tweak this number, and the Bots may show a greater interest in the area that is giving you problems.

    PATHING TIP: Then there is the dreaded "camping" problem that sometimes happens even when a level seems to be pathed correctly. I have found that the only thing that usually works is to (sometimes drastically) change the weapons and items placement, not just the pathnode placement. Even then, be aware that the problem may not entirely go away. A different kind of problem is seen when dealing with an area that the Bots just won"t frequent. (This often happens with "dead-end" rooms and areas. Remember it is best to design your levels where there are NO "dead-end" areas. Make sure that every area has an entrance and an exit for better game flow and for better routing. If you simply must have a "dead-end" area, make sure that you have something really significant in that room that will give the Bots a reason for going there.) If you follow the Bot around in Spectator Mode, you will realize that in almost any level the Bots tend to follow a predictable path. This path may leave certain areas out of the Bots territory. This problem too, demands a sometimes radical solution—change the weapons and items placement. This is a frustrating solution to an aggravating problem, but it usually does work. Don"t give up! Keep at it until the level flows smoothly and works well in Bot play. If one pathing or weapons and items placement does not work, try another.

    PATHING TIP: To get the Bots to "use" a button or switch, you must place a Trigger in front of the button. The Trigger must be set so that it will "push" the button AND also activate the object you want the button to open. This is rather complicated, so for purposes of illustration, let"s assume you want a button or switch to open a door. FIRST, put a Trigger in front of the button and open its Properties Sheet. Under Events, you see a field for Event and Tag. In the Event field put "Door" and in the Tag field put "DoorTrigger." Under Object of the Properties Sheet for the button the Initial State should be "NormalTrigger." Under Trigger of the Same Properties Sheet, put "True" for InitiallyActive and "False for TriggeronlyOnce. For TriggerType put "TT_PlayerProximity." SECOND, go to the Properties Sheet for the button or switch (the button or switch is actually a "Mover") and under Events, in the field for Event put "None" and in the field for Tag put "Door." Under the Properties Sheet, Mover, for the BumpType put "BT_PlayerBump." And Under the Properties Sheet, Object, for the InitialState put "TriggerOpenTimed." THIRD, go to the Properties Sheet for the door (this is also a "Mover") and go to Events. Under Event put None and under Tag put "Door." Under the Properties Sheet, Mover, for the BumpType put "BT_PlayerBump." And Under the Properties Sheet, Object, for the InitialState put "TriggerOpenTimed." (NOTE: There are quite a few other fields that you can choose to effect various aspects of the button and the door, but the above fields in the Properties Sheet tie the trigger in with both the button and the door. What you have basically done is make the trigger activate the "Door"—the name of the Events Tag for BOTH the button mover and the door mover. By the way, you should realize that you must set the time delay for the door so that it will stay open long enough for the Bots to actually go through that door. What is more, there must be something behind that door that is worth getting—like a SuperHealth or a weapons cache. Then that door must stay open long enough for them to get out of that room.)

    PATHING TIP: One of the hardest things for the Bots to do is navigate through water. (Perhaps the best advice is this: Do NOT put any pathnodes in the water unless you have to!) If you must have them "take the plunge" make sure that there is a very good reason for them to get all wet. Some good reasons would include items and weapons in the water (If you place items in the water, you should raise them off the ground about a foot or so. Otherwise, the Bots will get hung up trying to get the item while in swimming mode.), or the need to move into another area of the level. Do NOT make the Bots wander through underwater labyrinths just for "fun." (The Bots have a nasty habit of drowning, especially in deep water. In fact, it looks like the Bot"s AI does not always tell them to go UP for air! Another little problem the Bots appear to have is that sometimes they stop swimming and go into a walking or running mode underwater. This almost always means a sure death, unless their swimming AI kicks back in.) Place the pathnodes in the water like you do on land. However, if the water is deep, you may have to move the pathnodes (up or down) into the most efficient path possible. (Sometimes, for some unexplained reason, the pathnodes under water do not always connect properly, especially if the water is deep. Make sure that you go back into the water after a Path Define to check that all the water nodes are linked properly.) Always put pathnodes at the water"s edge, and put several of them at various points along the water"s edge so the Bots can easily jump out of the water. One or two more things, do NOT place any pathnodes above the water. And, remember, you can use the liftexit and liftcenter nodes in and around water. But, use them only to get the Bots in and out of water areas. Do NOT use these lift nodes to try and get the Bots to move through vast underwater areas. These elevator nodes will cause the Bots to pause at the various points (or sometimes change direction) and then all they will do is choke it all down. (And, don"t even think about trying to path the Bots through acid, slime or lava.)

THE ELEVATORS

Do NOT use "PathNodes" (Golden Apples) for the Elevators—they do not work! Instead use the "LiftExit" and "LiftCenter" nodes. (These nodes look like a Griffin"s head.) Place the LiftExit node where you want the Bot to WAIT for (or get off) the elevator. But, do NOT place the LiftExit too close to the actual elevator brush itself. If you do, and the Bots get too close to the elevator, they will active the lift too soon. (Use the same procedure as you would a regular pathnode. Point at a spot on the floor just outside the elevator platform brush and right click to place the LiftExit.) You must have at least TWO LiftExit nodes. One for the bottom of the elevator and one for the top. (You can have more than one entry or exit nodes, but it is best to only have one for each floor.) Place the LiftCenter node in the center of the elevator area, on the floor where the elevator brush is. This is where the Bot will stand and wait until the elevator reaches the top—if you do everything else correctly. (NOTE: Do not place any nodes, of any kind, in "mid-air"—floating far above the ground. They must be placed at approximately "waist-high" level above the ground.)

This next step is CRITICAL to getting the Bots to use the elevators properly. (In other words, to keep them from jumping off the elevator too early, or to keep them from standing under the elevator, etc. EACH ELEVATOR MUST BE GIVEN A UNIQUE NAME, AND EVERY "TAG" ("LIFTTAG") MUST BE SET ACCORDINGLY, AND THE ELEVATOR"S MOVER PROPERTIES MUST ALSO BE SET PROPERLY! Each elevator node (LiftExit and LiftCenter) has its own properties sheet. Right click on them and you will find their properties. When you are in the LiftExit Properties choose "LiftExit" and then "LiftTag"—Give a name to that tag that will be used for that elevator and all its tags. (Each elevator MUST have a different name.) Do the same with the LiftCenter LiftTag—give it the same name that you gave to the LiftExit for that elevator. NOW, and this is absolutely essential if the Bots are to behave themselves on the elevator, you MUST select the elevator brush, then right click that highlighted (pink) brush and choose "Mover Properties." This will give you the Properties Sheet for the selected elevator. On this Properties Sheet choose "Event" and then "Tag." Give the elevator the same name as its LiftExits and LiftCenters. This will "link" the elevator with the LiftExits and the LiftCenter nodes.

Bot Trivia: Did you know that the Bots can "call" elevators, but you can"t? It looks like the Unreal Bots know how to "push all of the elevator"s buttons" to use the elevators to their own advantage. If the Bot is at the top of an elevator shaft and the elevator is on the ground level, the Bot can actually summon the elevator. Hey, we can"t do that!

THE PATH DEFINE

If you have completely pathed the level and properly pathed the elevators as well, the next step is to go to "Options" and choose "Rebuild." Under Rebuild, choose the "Lighting" tab and then you will find the "Paths Define" button. Press this and the level will be processed and pathed. (This can take several minutes!) After the level is pathed, choose "Close." Then go to "File" and SAVE THE LEVEL. (Of course, you should be saving the level all along at various stages of development.)

AUTO BOT TIP

You can make your level automatically add Bots by going to Options, Level Properties, Level Info, and under Default Game Type put: Class"Unreall.DeathMatchGame" (The way you place this in the field is to, under Browse Classes, choose: Actor, Info, Game Info, Unreal Game Info, and then highlight "DeathMatchGame." Then in the Level Properties field for "Default Game Type"—which probably says "None"—click on the field and then select "Use." Because you have highlighted "DeathMatchGame," this will be placed in that field. Be sure and save the level now.) This will automatically bring Bots into the game when you start the level. So, you can just double click on the name of the level in Windows Explorer to fire up a game (and then close Explorer when the Unreal Log starts) and you don"t even have to fool with the BotMatch Menu! (This option reads your Bot Configuration file in the unreal.ini, so make sure that you have at least one Bot selected for BotMatch.) If you want to bring in other Bots, just go to the console and type in: addbots x (where "x" is the number of Bots you want).

THE FINAL STEPS

Unfortunately your mission to create a killer Bot level is not done. There are a few more steps that you really must take, if you want your level to be a top Bot level. First, go back into UnrealEd and load the map. Go through the level in the 3D view and look at ALL the pathnodes. Are the pathnodes and their links neat or sloppy? (It does usually make a difference! Remember, you are actually laying out the exact route that the Bots will take through the level.) Especially pay attention to trouble areas—like stairs or areas around lava or portals! Look for any pathnodes that are too far off the ground. Also, while in UnrealEd look at each elevator and their special pathnodes (LiftExit and LiftCenter) to see if they are placed and linked properly. And, if you are really brave, turn the "View Paths" option on and follow the pathnodes, looking for any broken (i.e., unconnected) links. All of the paths will appear as blue and red lines that connect all of the nodes and items. Fix any problems and then do another "Path Define" and save the level.

Secondly, whether the level was tweaked or not, go into Botmatch with ONE Bot and use "Spectator Mode" to follow the Bot through the level. Look for problems: areas where the Bot gets stuck and run in place; areas where the Bot does not go; excessive camping; etc. Then add one more Bot and watch them interact for a while. Next add several more Bots into the level and go spend time in each room/area looking for any problems. This second step will catch things you can"t see in UnrealEd. If Bots don"t move through a level, even if the pathnodes are great, you may have to change weapons/items placement. Sometimes Bots will just get stuck on several items if they are placed all in a row. To fix this, you have to break up the items placement—avoid straight line series placement of ammo and health. Sometimes you just have to delete and then re-place the item that gives the Bot a problem. You should realize that some Bot problems will be solved by just having another entity (Bot or human) to interact with, but observing a single Bot in the level while you are in Spectator Mode is very revealing. Watching the Bots, you really begin to notice all kinds of things that will teach you the ways of the Bots.

    For a variation of the "Spectator Mode" you can also go to the console while the Bots are in play and type in "viewclass femaleonebot" (or femaletwobot, maleonebot, maletwobot, malethreebot, etc. depending on which Bot you have in the game).

Finally, go into Botmatch and go one-on-one against the Bot on your level. Then bring in a few more Bots for a good old fashioned free-for-all. The better you have pathed and optimized the level for the Bots, the better they will play . . . and the more you will die!

Yes, this is a lot of trouble! But it is an essential part of quality level design. Remember, our ultimate goal is not to just build a good level for human deathmatch play, but also to build a better level for the Bots.

CLOSING HINT

If you run across a level that someone else made and the Bots don"t play it well, you can always fire up UnrealEd and follow all the steps in this tutorial to make your own Bot improvements. (But, if you want to re-release the Bot improved level, please be sure and get the permission of the level designer first.)


Pathnoding Unreal Levels for the Unreal Tournament Bots

by: Randar
mimpchnk@uswest.net

Now, familiarize yourself with UnrealEd2. Here are some of the basic changes you need to be aware of. After loading a level go to "View" and select "Actor Class Browser." Here you will find the "Navigation Points." To build the pathnode network after laying out the paths for the level, go to "Build" and choose "Rebuild AI Paths" (or choose "Build Options"). To show the paths, right mouse click on the top viewport bar and you will find the "Mode, View, Actors, Windows" menu. Then select "View" and "Show Paths."

The following are basic tips I have learned from pathing the Unreal Tournament levels for the Unreal Tournament Bots. I will be adding to them from time to time. If you have any tips, let me know, and I will give you proper credit.

    The Bots can do Hammer-jumps and use the Jump Boots. But, make sure their is a reason for them to make these jumps. Place an item in the immediate area that the Bots are to jump to. (In other words, do NOT expect the Bots to do most jumps if there is nothing for them to actually get when they make the jump.) Also, set the bImpactJump (in the JumpSpot"s properties sheet) to true for the Hammer-jumps. Next, be sure that you place Jump Boots in the general vicinity of the jump that you want them to make. If you put the boots at one end of the level, and the jump is at the other end, the Bots will rarely, if ever, make the jump. But, if the boots are in the immediate area of the jump, they will first run and get the boots and then go to the Jump Spot.

    Kickers are sometimes a pain. It is actually the LiftExits at the beginning and the end of the Kicker path that help the Bots get on and off the Jumpad. The JumpSpot (not the LiftCenter—the JumpSpot is a special LiftCenter) at the top tells the Bots where they are supposed to land and the second LiftExit completes the jump. (Hint: Set the JumpSpot"s bAlwaysAccel to "True." In fact, this should probably be set to "True" for any and all kinds of jumps including hammer jumps, jump boots or jumpad jumps.) Thus, there must be a LiftExit at the bottom of the jump, in front of the JumpPad; a JumpSpot that the Bot jumps to; and a final LiftExit near the JumpSpot at the top of the jump. Make sure these nodes have the right (same) names or tags. (Also, don"t forget the Triggers on the Jumpad for the sounds, etc.) One of the best ways that I know to learn how to node for the Kickers is to go into a level that you are sure is done correctly and look at the Kickers with their associated JumpSpot and LiftExits. Then do what they have done.

    The Bots always seem to have trouble going through portals. They frequently get hung up in them. To correct this, the best solution that I have found (and I have tried everything) seems to be to put an item on BOTH sides of the portal just a short distance from the actual portal itself. This seems to make the Bot "see" through the portal and then move through it to get that item.

    To make the Bots "trip a trap" or "use" a button make sure that you put a pathnode up against the button or trigger. In other words make sure that the network path created by a path define "forces" the Bots to go through the area of the trigger device. (If you have too many paths in the area of the button, the Bots may take them rather than the path to the button. If possible, try to force the Bot to take the path to the button or trigger by making it the only path available.) Now, with all of this said, you can"t make the Bots "time it right" so that they catch other players in the trap. It will just be a random thing.

    One of the most obvious things that could be done, that is not apparently being done by too many mappers, is to go into "Spectator Mode" and watch the Bots play the level. First put in one Bot and watch it for five minutes, then put in several more, and watch them for another five minutes. (Switch between the Bots by pressing the "Fire" button on the mouse.) This simple test will uncover most any problem with the pathing in the level. What, of course, you are looking for is any problem area. Do the Bots get hung up on something? Do they get caught in a loop? Do they get all the items? Do they go into every part of the level? Do they make the jumps? Do they use the elevators correctly? Do they go through the portals?

    In CTF maps, Salvation let me know that if the Bots don"t go for the flags the only thing you can do is delete the flags, replace them, do another "Path Define" and then it should work. Now, The-Crow has just confirmed that this does work. I have also found this little hint to work in other situations as well. For instance, I have found some lifts that refuse to work, even though it looks like everything is okay. I deleted all the related nodes and laid down fresh ones, did another "Path Define" and it came back to life. Try it on dead links.

    Latch sends in this tip: "With some help, I"ve found that the height of the flagbase actor is critical. If the flagbase is too high, even though it is still attached to the floor and has blue paths to it from other nodes, the bots will ignore it. They"ll run right by it. Simply lowering the flagbase so that its node-path connecting point is more even with the blue paths fixes it."

    I have noticed that when you fire up a map in UnrealEd, the log will give you an error if you use "BumpOpenTimed" on your movers. The message tells you that Bots do not understand this. So, use "StandOpenTimed" instead. This brings up another interesting point. Read the log file that is created when you build and play a map in UnrealEd. It gives you a ton of information about your level and may point out a few problem areas.

    Sometimes a Bot will appear to get "stuck." For instance, it will run into a wall and keep running. It actually looks like the Bot is trying to get something that is not in the immediate network of nodes. Well, it is and thanks to AlleyCat here is a tip to actually find out what the Bot is trying to do when it gets stuck. "Join the map as a Spectator, use fire to view from the Bot of your choice, then hit TAB and type VERBOSE. This gives a running insight in to what the Bot is actually thinking, even the pathnode number that he is after. (In UnrealEd the pathnode number is in it"s properties under Object/Name)" After you find the pathnode or item that the Bot is trying to get, that is causing the problem, move it out of the way. That should solve the problem of the Bots running into walls.

    Now, all of you probably already know this one, but it took me forever to find the answer to this frequently asked question: "What is the difference between the red and blue paths after you do a "Paths Define"? Well, it is simple. BLUE lines from node to node are the best routes, and the Bots will usually choose to take these paths most frequently. RED lines mean a less desirable route. The Bots will take red routes, but blue is better! Sometimes by tweaking (i.e., moving) the nodes you can change a red path to a blue one. But, sometimes, no matter what you do, the path will remain red. Just remember: BLUE IS BETTER! There, now you know.

    Well, here is a little problem that apparently is a "bug" in Unreal Tournament. I have noticed in a couple of maps that have TWO Invisibility power-ups, that when you or a Bot picks one of them up the game crashes with a Critical Error message. The solution is to delete one of the Invisibility power-ups, re-do the Path Define, and have only one Invisibility per level.

    I am amazed that I am still finding so many maps that are not properly pathed for the Bots. (Even some of the major UT Map sites are not catching the glaring pathing errors in some of the better maps they have reviewed. Many of the maps that are getting high scores are Bot-broken.) Some of the UT maps I have downloaded have pathnodes, but a "Path Define" was never done. Other maps do not have the elevator"s LiftExit and LiftCenter nodes properly tagged and placed. And some mappers are just putting JumpSpots in the level without the proper LiftExits and their tags. This will never do. PLEASE read the tutorials listed above! I have even found the need to go back and re-read Polge"s tutorials to figure out a few Bot-problems. I actually missed a few tid-bits on the first read. So, my advice is to read it again.


Unreal Tournament Mapcenter

Creating a CTF map for Unreal Tournament

By : Lode Vandevenne

lode@altern.org

Lode's Unreal

Download the zipped version of this tutorial.

Table of Contents:

Assumptions
Introduction
The geometry of a CTF-map
Placing the flags
The flagbase proporties
Startlocations
Bots
LevelInfo
Creating a CTF4-map
The future

Assumptions:

I assume that you can create a map with UnrealEd(2).
Oh yeah: if you want your map to be able to play with bots and don't know anything about pathnoding, read Randars "Pathnoding Unreal Levels for the Unreal (Tournament) Bots", and also check the bots section of this tutorial.

Introduction:

There are some dificulties and things to know about making a CTF map, so I made a tutorial about it :)
You'll learn about the geometry of a typical CTF-map, how to place flags and how to give them to a team, how to give playerstarts to a team, and how to make the bots take a flag.

This tutorial is optimized for UEd2, but if you have UEd1, you can use this tutorial as well, because these two versions don't differ that much. And I've added remarks for UEd1 when there is a difference. You can of course apply the official UT 420, 425 or 428 patch to get UEd2.

It could be handy to print this tutorial. (I always print them with the multiple pages per sheet option to save paper and ink)

The geometry of a CTF-map:

Before you can place flags, you'll need a map. Keep the following in mind while creating it (do not add playerstarts yet, as I'll handle them a little furhter in this tutorial):
-Make a CTF-map as symmetrical as possible, otherwise you'll advantage one of the teams and that's not fair. Also make the weapon and powerup placements identical for both sides (Do not place reedeemer, rocket launcher and flak in the red base and give that poor blue team only a sniperrifle and a chainsaw).
It is possible to make a non-symmetrical CTF-map that does not advantage one of the teams, but that's really difficult. An example of this is CTF-EternalCave.
-Add some red lights and red textures around the red base, and blue lights and blue textures around the blue base. This way, the players can see in which base they are.
-Do not make places where a player can get in but never get out anymore (for example a deep pit), because if a flag carrier goes in there, he will not be able to bring the flag to the base, and will have to suicide which means the flag will go back to the enemy base.

Placing the flags:

If you haven't yet opened the actor class browser, open the menu "View" and there choose "Actor Class Browser". In the browser, expand "NavigationPoint" and there select "FlagBase".

.

Now go to the 3D view and right click with your mouse on a place where you want a flag. In the menu that appears, choose "Add FlagBase Here".

You should now see something like this:

Now do the same thing for the other side (there are always two flags in a normal CTF-map) and rebuild geometry and lights. If you don't know how: look for these buttons and press them (or open the build menu)

You can of course do a BSP rebuild as well:

If you have UnrealEd1 (and searched but really didn't find the buttons from the screenshots :), go to "Options" and choose "Rebuild" then press the "Rebuild Geometry" button (also check the other tabs for rebuilding lights & BSP)

The flagbase proporties:

You now have placed 2 flags, but they aren't completely ready yet. You'll have to tell the editor which flag is for which team.
Select the red team's flag and click on it with right mouse button. In the menu that appears, choose "FlagBase Proporties"

In the "FlagBase Proporties" window, expand "FlagBase" and set "Team" to "0", which is the red team. Now select the bleu team's flag (and make sure the red flag is not selected anymore), and now set its "Team" to "1", which is the blue team. Don't worry about the color of the red flag being blue in UnrealEd, the colors will be correct in the real game.

If you want, you can change the sound that you get when someone takes the flag. But you don't have to do this! There already is automaticly a TakenSound selected, and I think that's the best sound you can have when taking a flag. But if you really want to change it: in the menu "View" choose "Sound Browser", then in the sound browser select the sound you want. Then go to the FlagBase Proporties and choose "TakenSound", then click "Use". Now the name of the sound you selected in the soundbrowser should appear. Again: you don't have to do this!

Startlocations:

Now, you'll have to create startlocations for each team. To add a playerstart, open the Actor Class Browser, expand NavigationPoint and select "PlayerStart". Then, in the 3D view, right click on the places where you want the playerstart and choose "Add PlayerStart Here"
Create as much playerstarts for the red team as for the blue team. About 5 playerstarts for each team should do, but larger maps need more. Don't place them on random locations of your map, but on strategic places, and remember to keep it symmetrically.
After that, select all the red-team playerstarts (hold CTRL while selecting to select more than one at the time) right click on them and choose "PlayerStart Proporties". In the PlayerStart Proporties window, expand "PlayerStart" and set TeamNumber to "0".
Now select all the blue-team playerstarts and set their TeamNumber to "1"
Do not place red playerstarts in the blue base and do not place blue playerstarts in the red base (unless you want to make a really special CTF-map :)

Now, you need to Build Paths. To do so, click the Build Paths button, which is next to the Build Lighting Button on the top toolbar of UnrealEd2 (see picture)

If you have UnrealEd1, go to "Options" and choose "Rebuild." Under Rebuild, choose the "Lighting" tab and press the "Paths Define" button.

Bots:

To make bots get flags, you'll first of all have to add path nodes, if you don't know how read Randars "Pathnoding Unreal Levels for the Unreal (Tournament) Bots" tutorial.

Then there is another important thing: make sure your flags are standing with their tips IN the ground, if your flag stands to high the bots will ignore it (see pictures below). To raise or lower a flag (or any other object), select it in the 3D view, and then hold BOTH mouse buttons and move your mouse, or go to one of the side views and just hold left mousebutton while moving.

If you test your map and see that the bots ignore the flag, first of all check if there's a path leading to the flag (to see paths, right click on overhead view and then show paths). If there isn't a path, add more pathnodes. If there is a path but bots still ignore flag, lower it and rebuild.

After you placed pathnodes etc..., don't forget to do another path rebuild!

LevelInfo

Before releasing your map, you have to set your "Levelnfo". Open the level proporties (in the Menu "View" or press F6).

-Enter your name at "Author"
-Set DefaultGameType to CTFGame. To do this, open the Actor Class Browser, expand Info --> GameInfo --> TournamentGameInfo --> DeathMatchPlus --> TeamGamePlus and there select CTFGame. Now go back to level proporties and click on DefaultGameType and there click the use button. You should now see the text Class'Botpack.CTFGame' appear.
-IdealPlayerCount: how many players you think are best to play the map. For example if you think 4 people par team is good, enter 8. You can also say for example 4-16, which means the map is playable from 4 players to 16 players.
-Screenshot: The screenshot that appears in the menu of UT when opening the map. Don't forget the screenshot must be a 256*256 picture, 8 bit color, imported into the package "MyLevel" with the name "Screenshot" and with Generate MipMaps unchecked. It IS possible to use an animated screenshot for your map :)
-Title: the name of your map :)

Creating a CTF4-map:

There is a nice mod for UT, CTF4. Go to it's homepage http://www.uncommonplace.com/ to download the newest version and CTF4-maps. Creating a CTF4 map is very simple: just add 4 flagbases and set there team numbers to 0,1,2,3 for respectively red, blue, green and gold team. When installing this mod, a FlagBase4 class will appear in your editor, but it's ok to use the normal FlagBase class. FlagBase4 is old garbage from a previous version of the CTF4-mod. Read the readmefile that comes with the mod for more about making a CTF4 map! Make your CTF4-maps symmetric in four directions. You can also make CTF4 maps with only three bases, so it becomes a 3 team CTF map.

The future:

I WILL update this tutorial.
If you have any questions, suggestions or found an error or grammatical mistake, please e-mail me at hybrid6666@yahoo.com.

(c)2000 Lode Vandevenne


Creating CTF Maps

By Trevelyan

Presumptions:

You should have a decent knowledge of UnrealED, such as playerstart actors, brushes and the like. You don't need to be an expert to make CTF maps, just that you need to be real good at making maps fun in order to make good CTF maps. Balance is the most key element! I will dive into this a bit later. For now, let's get started.

Directions:

This tutorial will cover the most important elements that must be needed to make a functioning CTF map; the actual map that I will show you is so simple it can me made in under a minute! Keep this in mind, as I'm not that bad at making maps J

First things first: Make a large room, any way you would like. To decrease confusion later on, add colored lighting on both sides (red and blue) and make a spot where you want your flag. I used this map as an example of this:

As you can see, it's a very complicated process. This room is roughly 1000X500 with 500*units in height. Now what are we missing? Flags you say??

Go to your classes on the right hand side. Select this actor:
Navigation point > FlagBase
And right-click on each flag holder to add your flagbase. Don't worry about the color of both flags, as UnrealED will display them as blue no matter what. Double-click on each flag and bring up the advanced properties:

What tells UnrealED which team is which is dependent on the team number shown above. Generally, red is 0, and blue is 1. Make your red "base" team number 0, and blue number 1. Now, if you haven't noticed, in every CTF map players will always spawn on their team's turf. Therefore, we shall learn on how to do this next:

Select Navigation point > Playerstart and add 2 playerstarts on each side or "base". Double-click on each playerstart and bring up its advanced properties. Select playerstart on its properties and highlight Team Number. You should know what to do at this point; however, do note that you do not adjust the properties for navigation point, which has a similar team number box.

Now rebuild your level, and make sure you save it as a CTF map (make the filename start with CTF-) before you test it, as the default game mode for map testing is Deathmatch, meaning it won't work unless you open the map manually once you boot up UT.

Conclusion:

This covers the basic elements of a CTF map. Make sure you don't plagiarize my map shown, or I will make it a point to sue you ;) However, when making your CTF map you may want cannons, covered in my other tutorial. You will also need to add some more difficult-to-add pathnodes in order to make the bot pathing work even remotely well. (Again, not to plug Silencer and myself, but this is also covered nearby!)

Any questions are more than welcome (please, send some!) at connors@nnex.net


Basic Cannons

By Trevelyan

Presumptions:

None, other than that you want to put those irritating cannons that you see in assault and CTF maps. (Irritating unless it's your cannon J)
Please do note that I intended to include the picture and made the quality of it a bare minimum so you can view it quicker. Thanks for not thinking poorly of me J

Directions:

Okay. You have made your CTF map and players are spawn killing away at the starting location for the opponent's base while the other players are grabbing the flag. What's the easiest solution? I think you know.

Bring up your classes menu and select this actor:

Pawn
>>>>Stationary Pawn
>>>>>>>>>>>>>>>Team Cannon (or Minigun Cannon)
And place the cannon in a strategic location. You will need to adjust the direction of the cannon as well.

All of the advanced properties for the TeamCannon are self-explanatory. The default shots that are fired out of the cannon are the AMSD blasts. To change this, highlight Projectile type and then clear the field. Go to your classes and select Projectile on the list; from there click on what kind of shot you would like (such as the WarHeadShell… Give that one a shot!), and click on Use in the Projectile Type box. You will want to change the Fire Sound to accommodate this as well. All you do is clear the fields like above and go to your Sound FX class and select whatever you feel like. (Most sounds that you need are under Botpack.)

Conclusion:

I believe that covers all that you need to know on cannons as far as how to create them. The strategic value of them is something that you need to come up with however. Experimentation is the most enjoyable element of UnrealED! As usual, please give me an E-mail if you have any comments or questions at connors@nnex.net.


How to Create Teams

HOW TO CREATE TEAMS IN UNREALED...

By: Sliencer

utcity@planetunreal.com

UT City

FOREWORD:

I am suspecting that you know how to create a simple CTF level with lights, flags, and pathnodes.

DIRECTIONS:

First create a level or use one that you already have made. Now in the Browse Drop Down Menu Bar on the top right area of your screen select "Classes". Now look for a phrase called "*NavigationPoint", you should see a small minus sign next to it. Click on it. A drop down menu should appear before you. Now with you cursor select "*Playerstart" (Note: If a blue box appears close it.). Now in your 3D view right click where you want to place the player to start. Then select "Add Playerstart here". You should notice a small item like a handlebar appearing on the place where you selected, if not then try again. Then go to a new area and place one there (Of course I reccommend doing more than one playerstart in a real map but for this tutorial we are just using one to two each. Once your playerstarts are in place go ahead and select all the player starts (If more than one you are selecting-hold the CTRL key while you select each one.) that you want for team 1 (Red Team). After all are selected right click on one of the playerstarts and choose Playerstart Properties. Now you should see a new box with the words Playerstart Properties on it. Good. Next to where it says Playerstart, click on the + sign. A pop down menu should appear. Now look where it says TeamNumber, on the right of it you should see the number 0. Click on that 0 and delete it and put 1. Now close the box up. You will NOT have to do the other team because the default is always set to team 0 which we want any ways. Now go ahead and rebuild and test it out. Make sure that you've placed flags and pathnodes for the bots to both flags or the teams won't work correctly. You'll get both teams starting in scattered areas and not in their correct zones. If you get one team of red in one area and a team of blue in another then you've done it correctly.

Note: The following TeamNumber attributes determine the color of the team.
Blue Team: 0
Red Team: 1

CONCLUSION:

Teams can be used in Domination, Assault, and Capture the Flag modes only. In the advanced tutorials I will teach you how to make secondary team playerstarts.

OTHER:

For comments/questions email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


CREATING ASSAULT LEVELS...

By: Sliencer

utcity@planetunreal.com

UT City

FOREWORD:

I am suspecting that you have the geometry and lighting ready, and that you know how to use pathnodes in a level. You must also know how to put tags on objects such as pathnodes.

DIRECTIONS:

Part I    :  Teams
Part II   :  Fortstandards
Part III  :  Defense Points
Part IV   :  Other

Part I - Teams

The first thing you want to add to your assault level is teams because without them, it's not an assault level, it's a deathmatch. Place playerstarts in two seperate areas, one for the attackers, and one for the defenders. Assign the attacking team's team number to 1 and leave defending team's team number to 0. (If you don't know what this means please read the "How to Create Teams" tutorial on this site.) Good, step 1 done, now you've got your teams. Note: You can add secondary starting points for both teams, please read the "Secondary Playerstarts in Assault Maps" for more information.

Part II - Fortstandards

Fortstandards play a key role in making assault levels. Fortstandards set off events, they tell the computer where to go and defend, they tell the attacking team what to do, and they help in explaining the mission objectives with the AssaultInfo object. The Fortstandard object can be found in the Classes Menu, under Pawn, then under StationaryPawn(See picture below.)

Place the fortstandard(s) in the locations where you want the attacking team to reach in order to complete a certain objective. Starting with the last one you've placed right click on it and go into it properties box. Now under the Collision properties section go down to Collision Height and Collision Radius. This is the area in which the player/bot can either come into contact with it or the area in which a weapons projectile can hit it. For example, if you made a hallway that was 256 in hieght and 256 in width and you wanted the attacking team to reach that hallway. You would put the collision height to about 128 - 256 and the collision radius to 128 - 256. Ok, now if you want your Fortstandard to have an event when it is either activated or destroyed set the Event under the Events attributes to whatever it is that you want the Fortstandard to trigger. For example, if you wanted to make a player/bot activate a button or a switch by running into it, you would create the usual mover and place a fortstandard right in front of it. Then you would set the mover so that it would be TriggerOpenTimed and you would put a tag on it. Then on the Fortstandard you would set the Event under the Events attributes to whatever it was that you set the mover's tag too. You would also have to set the bTriggerOnly attributes under the FortStandard's attributes section to true, meaning that the attacker would run into it and not have to destroy the fortstandard to activate it. Now away from that example and continuing on, go into the Fortstandard properties box and into the Fortstandard attributes area. You'll notice a lot of properties appear. The following explains what most of them do:

bFinalFort
This is set to True when this is the final objective that must be reached by the attacking team. This is only set to True on one of the Fortstandards in the level.
bFlashing
When this is set to True, the Fortstandard will flash blue lights on and off showing the attacker where to aim or get too.
bSelfDisplayed
When this is set to True, the Fortstandard is visible in the level during the game.
bTriggerOnly
If this is set to False, the fortstandard must be shot. If this is set to True, the fortstandard must be activated in some other way.
DefensePriority
This is a key property when dealing with more than one fortstandard. The higher the number is the earlier it is defended and attacked. For example, if you have three fortstandards, one at 2, one at 1, and one at 0, you would put the final fortstandard in the level at 0 and the first one at 2 because the attacking team will go after the fortstandard with the highest DefensePriority first and the defense team will gaurd that one first as well. Once that is conquered, the attacking team will go after the one that has a DefensePriority of 1 and the defense team will then defend that one next, and so forth.
DefenseTime
This is the amount of time given to both teams to attack/defend the level. The final fortstandard is the master fortstandard, this meaning that whatever you set the DefenseTime here is what it will be in the game. The default setting is 10 minutes.
DestroyedMessage
This is the message displayed during the game following the FortName after the attacking team completes it. For example. if you had a FortName of "The Gate" and a DestroyedMessage of "has been opened!", when that fortstandard has been completed, the message displayed to all players will say "The Gate has been opened!".
EndCamTag
This is related to final scenes or views after the assault level is beaten. It takes all the players/bots to the final cam view (which is a spectator cam object.) at the end of the mission. This property is set to the tag of the final SpectatorCam object tag assigned to it. (Since this could take forever explaining go to the "Creating 'Movie Scenes' in Assault Maps" tutorial located on this site.
FallBackFort
This property is assigned to the FortName property you put in you Defense Points. For example, an attacking team reaches the fortstandard and it has a FallBackFort tagged "F3", the defending bots will then go back to all the DefensePoints with the FortName tag in their Properties box set to "F3". Normally the defense points are placed at the next fortstandard where they should be guarding.
FortName
This is the name of the FortStandard that the defending team is currently defending. When you die while on the defending team, you see that under Orders or something it says, "Defending ______". For example "Defending The Gate". This shows you what your team is currently defending. It also relates with the DestroyedMessage property. (Read what that does to see what I mean.)
NearestPathNode
This is the tag of the pathnode that is nearest to the current fortstandard. You must tag the nearest pathnode first.

Below is an example of a fortstandard with assigned properties.

Part III - Defense Points

Defense points are used for the defending team to wait and stand for an attacking team to come and then hold that specified area as they defend. Defense points are where you can put stragtegic points for the defense team to guard. Near every fortstandard there should be at least one defense point. Also you must assign the FortTag property something unique. This way, when attackers breach an earlier fortstandard, the defending team will go the the defense points that the Fortstandard tells it too by using the FallBackFort property which is related to the FortTag. For example, you have two defense points with the FortTag property set to "zoo". The attackers then breach an earlier fortstandard that has the FallBackFort property set to "zoo". The bots will then fall back to all the defense points with the FortTag labeled "zoo". Now of course you don't have to label it zoo because I just picked that out of the blue. Every fortstandard has a FallBackFort property even though you don't have to put a FallBackFort tag. I reccomend that you place the defense points near the fortstandard that you have to defend because that's really dumb if you have defense points on the other side of the base that bots are going to defend when the fortstandard is on the other side. Ok, I think you get the picture. Any further questions email UT CITY.

Part IV - Other

There are a lot of little things that make up a good assault level. One thing that helps humans to understand where to go to complete the objectives is the AssaultInfo object. You may have noticed that in the beginning of every assault game it says "Press F3 for Objectives" or something like that. This is really, really helpful to humans when playing your map because the objectives may sometimes not be too clear. You can find the AssaultInfo object which allows you to place descriptions and screenshots of each objective in the Classes area, and under Info. You'll see a thing called AssaultInfo. Select it and place it anywhere within your level. Now right-click on it and go into its properties. Then go into the AssaultInfo attributes section. Now count up how many objectives there are in your assault level and write that number in the NumObjShots property. (I believe the maximum is 8.). Now go into the ObjDesc attribute section and expand it. You'll notice a set of numbers with brackets around them from 0 to 7. Put a description of how to reach and complete your first objective in the property area tagged "[0]". Then continue on to [1] with another description of the next objective, and so forth until you've provided descriptions of every objective in your level. Now go into the ObjShots and you'll notice again the numbers 0 - 7 with brackets around them. Here is where you place screenshots of where the objectives are located. To make the screenshots for each objective, do exactly what you did in making the main screenshot for your level but this time name every objective image Obj1, Obj2, Obj3, and so on. Placve them in the MyLevel texture package and click on use for each one. The number [0] corresponds with the first objective, the number [1] corresponds with the second objective, and so forth. (For more information on how to make objective screenshots and how to do what I just said go to the "Adding Screenshots to your Level" tutorial on this site.) Below is an example of an AssaultInfo object with properties. (Note: Not all of the objective screenshots are there because the map I was working on wasn't finsihed and therefore didn't have screenshots.)

If you've somehow understood what I've said then good, otherwise email me and I'll answer any questions of yours that I can. Another thing besides this tutorial that can help you is to look at some of Epic's assault maps in UnrealED and see how they constructed their's.

CONCLUSION:

You should now know the basics of creating an assault level using UnrealED.

OTHER:

Questions/Comments email utcity@planetunreal.com.

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


How to Create Secondary Playerstarts

HOW TO CREATE SECONDARY PLAYERSTARTS IN ASSAULT MAPS

By: Sliencer

utcity@planetunreal.com

UT City

FOREWORD:

I am suspecting that you are an advanced user of UnrealED, you know how to make playerstarts and assign teams, you have a level ready, and that you are familiar with dispatchers.

DIRECTIONS:

Since you’ve already got a level and know how to use everything, I’m going to just keep this brief. First right-click on the playerstarts that consist of your assaulting team and go to the events properties. Under the Tag attributes name these as: “attackerstart1” (without the quotes). Now right-click on the playerstarts that consist of your defending team and go to the event properties. Under the Tag attribute name these as: “defenderstart1” (without the quotes). Now create a second pair of attacking playerstarts and assign their team number as usual and name all of them “attackerstart2” (without the quotes). Now while still selecting the second set of attacking team playerstarts go into the Playerstart Properties and make the bEnabled attribute to False. Put the secondary playerstarts where you want your attackers to start after they’ve reached a certain fortstandard that you’ve chosen. Now create a second set of defending team playerstarts and assign their teams as usual. Under the Events>Tag Attribute name all of them “defenderstart2” (without the quotes). Now once again go into the Playerstart Properties and make the bEnabled attribute to False. Ok now you’ve got your playerstarts all set up so now all we’ve got to do is trigger an event that sets up the switching. Go to the fortstandard that the attackers must reach before they start in their new area. Under the Events>Event attribute, set it to “dispatch1” (without the quotes). Now create a dispatcher. Go into the properties of it. Under the Events>Tag attribute, set it to ”dispatch1” (without the quotes). Now under the Dispatcher Properties click on “OutEvents”, then you should notice a set of numbers with brackets around them. Under [0] put “attackerstart2” (without the quotes), under [1] put “defenderstart2” (without the quotes), under [2] put “attackerstart1” (without the quotes, and under [3] put “defenderstart1” (without the quotes). Now exit the dispacher properties dialog and rebuild your level and test it out. If it doesn’t work double check that you did everything exactly like I said.

CONCLUSION:

Well now you’ve learned how to add secondary playerstarts for your assault level. In the future I may be releasing yet another tutorial on how to add three or more sets of playerstarts!

OTHER:

Comments/Questions Email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


Creating "

Creating "Ending Scenes" in Assault Maps

By Silencer

FOREWORD:

For this tutorial you will need an in depth understanding of UnrealED as well as an assault map ready. You also, will need some ideas of what you want your "ending scene" to be in your assault map.

PARTS:

  • Part 1: Formulating an "Ending Scene"
  • Part 2: The Neccessities
  • Part 3: Explosion Scenes
  • Part 4: Explosion Chains
  • Part 5: Adding Smoke
  • Part 6: Adding Sounds
  • Part 7: Creating an Example Ending Scene

DIRECTIONS:

Part 1: Formulating an "Ending Scene"

Basically what this section is about is, is what you want your "ending scene" to be. Every assault map is different. For example, in AS-Bridge, the ending scene in that was a bridge blowing up. This was done because the main objective in the map was to place explosive materials (C4?) inside the bridge and then blow it up. Hence, the ending scene in AS-Bridge was a bridge blowing up. Your assault map's ending scene should follow its storyline. For example, what if the ending scene to AS-Bridge was a ship flying into outer space. Everyone who would see it would go, huh? It would have nothing to do with its storyline. That is why your ending scene must stick with the storyline.

Most of the ending scenes I have seen in assault maps consist of movers and explosions. Actually, I'd say about all the ending scenes in assault maps have either an explosion or a mover at the end (even both). Right now you should have some kind of idea you want your ending scene in your assault map to be. For example, if you had a space scene in which you had the attacking team get out of the base and into a ship, then you'll probably be thinking in something similiar to that of AS-Asthenosphere. Or, if your attacking team was supposed to blow up a dam, then you'll be obviously thinking of a dam explosion. So right now, take a look at your assault map and think of a cool ending scene to go along with it when the attacking team wins.

Part 2: The Neccessities

These are the things that are required in an ending scene:

  • A Fortstandard
  • A Spectator Cam
  • Movers and Explosions (Not totally neccassary but used 99% of the time)

Other things that are commonly used in ending scenes:

  • Triggers, Dispatchers, and Special Events
  • Ambient Sounds
  • Smoke

A Fortstandard:

No need to go deeply into the detail of this object. In case you don't know what this is or are unfamiliar with it. Go read my other tutorial on Creating Assault Maps . Basically, what we will be doing with this is taking your final fortstandard. The one that the attacking team must reach in order to win, and assigning it an event and a string for the EndCamTag. I will go into this with more detail later.

A Spectator Cam

Without this little thing, everybody's final ending scene would be looking at themselves like in CTF and Deathmatch maps. A spectator cam brings all the players in that game to look from it. For example, if you put a spectator cam in your level and faced it at a pyramid, and then assigned it as the final cam, and the attackers won, everybody would look through that spectator cam and not at themselves. For a better example at this go play AS-Pyramid and beat it. I will talk about setting up and finding the spectator cam later.

Movers and Explosions

Hopefully if you are reading this then you know about movers and exploding walls and such. If you don't know how to set up and exploding wall, no biggie, I'll explain it further down the line. If you don't know what movers are, go learn them first! Ok, now onto what these two things can do, explosions are exactly what they sound like. During an ending scene, you might was to have a wall explode and a tank come through the opening. What you would do is set an explosion to blow up the wall, and then have a tank (your mover) roll through that destroyed wall and into your movie. These two things basically make up your entire ending scene.

Triggers, Dispatchers, and Special Events

If you are gonna have an ending scene with sounds, smoke, and explosions, your gonna need to know how to use triggers, dispatchers, and special events. Without these objects, either nothing would set off or start, or everything would start at once making it look stupid. (ex. A tank goes through the wall before the wall is exploded) Many ending scenes use these three objects. In case you don't know how to use these objects, please find out how. Wolf's Tutorials or UnrealED.exe has tutorials on this.

Ambient Sounds

So what do these do in an ending scene? Well, ambient sounds help bring life into your ending scene. They make it feel just that much more realistic. When used correctly, ambient sounds can really boost up the performance of you ending scene. Epic has provided us mappers with lots of ambient sounds to choose from. Such as explosion sounds, elevator sounds, and even a waterfall sound. Ambient sounds can also be used in your level as well.

Smoke

Ok, lets say that you are making an ending scene and you've made it so that there's a large explosion and a building is destroyed. Now normally, in reality, there's a bit of dust and smoke after the explosion. So what smoke does in your ending scene is exactly that. It too, like ambient sounds, adds to the feel of your ending scene. Imagine a house burning down and there being no smoke rising from it, see, you get my point. Smoke is make with UnrealED through objects called SmokeGenerators which I will go through later.

Part 3: Explosion Scenes <<Download Test Map>>

Because later in the tutorial I will be going through making an example ending scene, here I will tell you how to set up an explosion. First off, make whatever it is you want to have explode. Then, make a large brush and intersect it. (Note: I'm not going to go through all the details as I suspect you already know this because this tutorial is an advanced tutorial.) Once intersected, right click on the brush and go to "Polygons", then click on "To Brush". Now move that brush to where you want the explosion to happen and create a mover. Set the first keyframe to somewhere outside your level. I will explain why later. Now go into the Actor Class Broswer and click on the plus sign next to "Effects", then scroll down until you see something called: Exploding Wall. Do not click on the plus sign next to that, just click on the Exploding Wall. Now place that near your mover. Now right click on your mover and go into its properties menu. First go into Events and set up an event tag with a unique name such as "gorilla" or whatever ;) Then, if you want this explosion to be triggered only and not shot, then set a unique Tag on it such as "ape" or whatever. Then go into the Mover section and set the following properties:

  • bDamageTriggered = True
  • bTriggerOnceOnly = True
  • bDamageThreshold = 20.000000 (Note: If you want this exploding "Thing" to be hit and damaged and not just triggered, make it a number like 20 - 40)
  • MoverEncroachType = ME_IgnoreWhenEncroach
  • MoveTime = 0.000000 (This is why you set the first keyframe to someplace outside the level. The mover doesn't really "explode", it just dissapears and chunks form.)

Ok, with that all set, go into the Objects section and set the InitState to TriggerOpenTimed. Then you're all set with the mover so go ahead and close its properties menu. Now right click on the Exploding Wall object and go into its properties menu. In the Event section, set the Tag to the event that you set the mover too. For example, I set the event in my mover to gorilla so I will set this tag to gorilla. Now go into the Exploding Wall section and do some testing with the following properties:

  • BreakingSound = Set this property with an ambient sound (an explosion one reccommended) - Ex. "Sound'DDay.(All).explo1" << This is an ambient sound found in the DDay.uax file
  • ExplosionDimensions = Test out different number sizes until you get what you want - Ex. 120.000000
  • ExplosionSize = Test out different number sizes until you get what you want - EX. 200.000000
  • GlassParticleSize = Set this to a number you choose for the sizes of the glass chunks - Ex. 12.000000
  • WallParticleSize = Set this to a number you choose for the sizes of the wood chunks - Ex. 12.000000
  • WoodParticleSize = Set this to a number you choose for the sizes of the wall chunks - Ex. 12.000000
  • GlassTexture = Set this to the texture you are using for your glass.
  • WallTexture = Set this to the texture you are using for your wall. - Ex. "Texture'Crypt2.Ceiling.C_clng1'" << This is a texture found in the Crypt2.utx file
  • WoodTexture = Set this to the texture you are using for your wood.
  • NumGlassChunks = How many glass chunks you want. - Ex. 8.000000
  • NumWallChunks = How many wall chunks you want. - Ex. 8.000000
  • NumWoodChunks = How many wood chunks you want. - Ex. 8.000000

Now close the Exploding Wall properties menu and press F8 and Rebuild Geometry. If using UnrealED 2.0, click on Comput Geometry, Compute Lighting, and Compute Paths. Once done with that test it out! (Only test it out if you made the explosion object (the mover) have a DamageThreshold for shooting out.) Unless you wanted to set the explosion off by trigger, go ahead and test it out, otherwise you have on more thing to do. Place a trigger into your level and go into its properties, under its Event section, put the name of the tag you put on that mover earlier into the Event property. Now, if you already had a level ready for this then put whatever event it is that sets off this trigger, otherwise go down to the Trigger Section in the Trigger properties menu and next to TriggerType, put TT_PlayerProximity. Now test it out after rebuilding geometry and lighting!

Part 4: Explosion Chains <<Download Test Map>>

Explosion Scenes and Explosion chains are very similiar, the only difference between the two is that explosion chains can be more than one explosion (hence the "chains") and they don't blow up chunks all over the place. To add an explosion chain into your level, go into the Classes broswer and click on the plus sign next to Effects to bring a new list down. Scroll down until you see something called: ExplosionChain. Now add about five of those in your level where you want the explosions to happen. You can add as many as you want but for this example, I'm using five. Ok, now, right click on one of the ExplosionChain objects and go into its properties menu. Now go into the Events section and give it a unique tag such as "boom" or something. Now, place the same tag for all the ExplosionChain's you've placed in your level. For this example, I would now have five ExplosionChain objects with their tag marked "boom". Now go ahead and select two or three of them and go into their properties menu. Under the ExplosionChain section, you'll notice some properties as listed below that you may want to play around with until you receive your desired effect.

  • Damage = The amount of damage it gives to a player/bot if near it when it explodes. - Ex. 60.000000
  • DelayTime = Time after the initial triggered event has been set before the explosion erupts. I believe it is in seconds. - Ex. 1.000000
  • Size = The size of the explosion. Keep this fairly low. - Ex. 1.500000

Now select the remaining ExplosionChain objects and set the properties to the same that you set the others but instead, change their DelayTime poperty to a higher or lower number. Now you will have a set of two explosions in the same explosion chain. Now that your ExplosionChain objects are tagged and set, add a trigger somewhere in your level where you want the person/projectile to be to set off the explosions. For example, if you wanted have a player walk through a booby-trapped hallway in which when he was in the middle the hallway's ends would be explode and therefore leave him dead. You will put your ExplosionChain objects on the ends of the hallway and put your trigger in between them. After you have found a good place for your trigger and have placed it there, go into its properties menu. Now, go into the Events section and under event, put whatever you put for the ExplosionChain tags; in this example, the Trigger's event would be labeled "boom". Now, under the Trigger section in the Trigger's properties menu, look down until you see something called TriggerType. Now, in trigger type you have five choices. One of them is TT_PlayerProximity and another one of the five is TT_Shoot. If you choose TT_PlayerProximity, the bot/player must run near the trigger to activate it. If you choose TT_Shoot, you must shoot near it to activate it. So choose which one you want. Now, rebuild geometry, lighting, and pathing and test it out!

Part 5: Adding Smoke <<Download Test Map>>

First I'll start off with explaining how to add smoke to your level/ending scene. To add smoke, go into your Classes broswer and select on the plus sign next to Effects. The scroll down until you see something called "SmokeGenerator". Select on that and place it at the exact spot where you want your smoke to come out from. Now, right click on the SmokeGenerator and go into its proprties menu (Note: You can always have more that one SmokeGenerator in your map). Now, because you'll need something to set off the smoke, you'll need to put a Tag on it, so go into the Events section and put a unique tag on it such as "smokin". Now go into the SmokeGenerator section and look at some of the following properties:

  • BasePuffSize = The median size of each smoke "puff" - Ex. 2.000000
  • RisingVelocity = Not positive on this one but I believe it is how high your smoke rises in units before it dissappears. - Ex. 75.000000
  • SizeVariance = +/- the range from the BasePuffSize - Ex. 1.000000 (This meaning that with a 2 BasePuffSize, the size of the puffs can be anywhere from 1 - 3)
  • SmokeDelay = Once triggered, this is time that it will wait before it starts. - Ex. 0.150000
  • TotalNumPuffs = Pretty Self-Explanatory, once this number reaches zero, the puffs/smoke stops. - Ex. 1000000.000000 (This will take a looooong time to run out)

Now that you've got your SmokeGenerator set up go ahead and make some more if you like following the same procedure. Once you've added all the SmokeGenerators you need, go into the Classes Broswer and select the plus sign next to Tiggers and select Trigger. Now add a trigger into your map and open ups its properties menu. (Now, the way you activate this trigger is up to you, whether or not you want it to be shot at or touched.) Now, while in the trigger properties menu, go into the Events section and put the name of the Tag you put on your SmokeGenerator into the Event property. Then you're all set, rebuild geometry, lighting, and paths and test it out!

Part 6: Adding Sounds <<Download Test Map>>

Ambient Sounds are very, very easy to add into your level/ending scene. First, go into your Classes broswer and select on the plus sign next to KeyPoint, then select on the item at the top of that list called AmbientSound. This is what we will be using to create our sounds. Now right click somewhere in your level where you want a specific sound to come from and add it there. Now right click on the AmbientSound object in your level and go into its properties menu. Now the only thing that we will be working with in here will be in the Sound section, so go ahead on open that part up. Now, before touching anything in the sound section, you're gonna have to find the right sound first for your area! So go ahead and open the Sound broswer. Load up the .uax file that you think would have to right sound in it and test it out by pressing the Play button to see if it is the right sound. If so, then keep it selected (the sound) and minimize the Sound broswer. Now go back into the Ambient sound properties and into the Sound section. Click on where it says AmbientSound, then click on the little button on the right of it that says "Use". There, now you've got the sound set up. Below you now are other properties that you can set to help your AmbientSound, sound more realistic. SoundPitch, SoundRadius, and SoundVolume all have to do with the area that you can here the sound and it's volumn. For one of my older levels, I put these all at 64 because I put this sound in a corner (It was a cricket sound). Once you are all set, rebuild geometry, lighting, and paths and test it out!

Part 7: Creating an Example Ending Scene

Now it's time to put everything that you've learned so far into an assault ending scene. To get everybody on the same page I've created a functional assault map that is complete with everything except the ending scene. While it may be crap, the ending scene that we'll make with it won't be. So " Click here to download the Map ". Once you've downloaded the map, play it by yourself and just run around in it a bit so you see what it looks like and where the final objective is. Then open up UnrealED and open it up in that. Ok, now that's it's opened up, we can start creating our ending scene. First off, we need to think of what would be a good ending scene for this map. Well lets see here....Ok, what will happen is the sphere in the middle will have too much power/energy in it causing it to explode. This is why I put the computer terminal in the map, it is controls for the amount of power going through that sphere in the middle. Once the attacking team hits that terminal, the power will switch on to max power causing the sphere to explode. Once the explosion has occured the pieces will then fall into the lava below and will be burned up, so we'll put some smoke in there too. Ok, first off, adding the spectator cam. Go into your Classes browser and go into the KeyPoint area. Then scroll down until you see something called SpectatorCam. Select that. Now right click on the top 2D view. You'll notice for a split second that a red arrow appears and then disappears (excuse my spelling if it's spelled wrong). Now, click on one of the blue brushes in the map and then right click on it in the top 2D view and then click on Select All. See below for example:

Then hold the Ctrl key and click on the red arrow to make it disappear again. Then click on the [image] Invert Selection button on the left side of the screen. (It looked like a button that is half black and half white cut in diagonal. Making sure that everything, including your red brush, is unselected, and that you can see the red arrow; hold the Ctrl key and the right mouse button and position it (the red arrow) in the 2D views to look at the sphere. See below for how I positioned mine.

While still having the red arrow (our SpectatorCam) still selected, right click on it and go into its properties menu. Then go into the Events section and put the following tag on it: "finalcam" (without the quotes). Now you can unselect that. Now go to where the computer thing is and select on the FortStandard right near it. This is our final fortstandard so we will be putting and EndCam property on it. Right click on the FortStandard and go into its properties menu. Now, go into the FortStandard section and scroll down until you see something called EndCamTag. Now place "finalcam" without the quotes into that property area. See below for example.

Once you are all set with that, save your level and start up UT and test the level out. Beat it and then it will take you to where you placed your SpectatorCam. If you feel that it is in a good position and is looking at the sphere and the lava, then great, you're all set. If you feel that it isn't positioned correctly enough to see the whole sphere and the lava below, go back to UnrealEd and reposition it by doing all that selecting stuff I said earlier. Ok, now that the hard part is done, it's time for the more easy and fun parts. First, lets set up the easiest thing, the smoke. Add SmokeGenerators around the lava area. See below for how I did mine. (Note: For more information on how to set up smoke, please go here .)

All those little black things are SmokeGenerators that I've placed on top of the lava. Now we have to set up all the SmokeGenerators. Select them all and give them all this tag: "Smoke1" - without the quotes. Now change their total number of puffs to about 500 and their smoke delay time to about 0.500000. Now go ahead and deselect those. The smoke is now all set, so save your level. Now we need to make the sphere in the middle explode so here's what we are gonna do. First set the sphere's first keyframe to somewhere outside the level. (Note: For more information on how to set up explosions, please go here .) Ok, now that's all set go into your Classes broswer and add an ExplodingWall object near or inside the sphere. Now all we gotta do is set their properties. Go into the sphere's properties (which is the mover) and put this Event on it: "explodeme" without the quotes. Then put this tag on it: "boom" without the quotes. Now go into the Mover section and set the following properties:

  • bDamageTriggered = True

  • bTriggerOnceOnly = True

  • DamageThreshold = 1000.000000

  • MoverEncroachType = ME_IgnoreWhenEncroach

  • MoveTime = 0.000000

And leave everything else alone. Now go into the Object section and set the InitialState property to TriggerOpenTimed. Now close the mover properties on open up the ExplodingWall properties menu. In the Events section and under Tag, put "explodeme" without the quotes. Now go into the ExplodingWall section and set these following properties:

  • ExplosionDimensions = 240.000000

  • ExplosionSize = 500.000000

  • GlassParticleSize = 0.750000

  • GlassTexture = Texture'Coret_FX.Base.A_Base1' (Explained Below)

  • NumGlassChunks = 50

  • NumWallChunks = 75

  • NumWoodChunks = 25

  • WallParticleSize = 0.750000

  • WallTexture = Texture'Coret_FX.Base.A_Base1' (Explained Below)

  • WoodParticleSize = 0.500000

  • WoodTexture = Texture'Coret_FX.Base.A_Base1' (Explained Below)

To set the Wall, Wood, and Glass textures, open up your Texture broswer and open Coret_FX.utx and select on the texture named A_Base1. See below for picture:

Then while selected, minimize the texture broswer window and go the the GlassTexture, WoodTexture, and WallTexture properties in the ExplodingWall object and select Use. Then you should be all set so close the ExplodingWall properties menu. Ok, now go back to the final fortstandard near the computer terminal and go into its properties. Go into its Events section and set the Event to "Time", without the quotes. Now close that and go into your Classes broswer. Go into Triggers and select on Dispatcher. Then add one of those into your level. Now go into the Dispatcher's properties. In the Events section under Tag put "Time", without the quotes. Now go into the Dispatcher section and select on the plus sign next to OutEvents to bring a list down. Under [0] - put "Smoke1", under [1] - put "boom" (both without the quotes). So now your Dispatcher properties should look like this.

Phew! Finally finished. Compute geometry, compute paths, and compute lighting and then save your level and test it out! If your level doesn't seem to work correctly, " Compare it with my Finished One ". Good luck!

CONCLUSION:

Well, judging that what I said was all correct, you should now know how to make ending scenes in assault maps and know how to set up Exploding Walls, Explosion Chains, Sounds, and Smoke. There's so many possible things you can do when creating ending scenes so experiment! I hope to be seeing some great assault maps soon! :)

OTHER:

-=[Copyright/Permissions]=-

Questions/Comments email me at Murphy149h@mediaone.net .

This tutorial is Copyright (c) 2000 Matt "Silencer" Murphy.

This tutorial is not supported by Legend Entertainment or Epic Games.


BB Drac - Unreal Tournament UED2 guide Assault explained

Assault Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

To understand this tutorial and basics behind assault maps,
you should have a some knowledge of triggers and bot AI if
you want bot support.

The level design will also turn out to be a bit different from
DM, CTF or DOM.
You need to focus more on flow and defend/attack areas for both
teams.

To actually create the assault level FortStandard actors is used.
It can be found in the actor browser under "Pawn" and "StationaryPawn".

For each objective you need one fortstandard.

This is a list of the properties you might want to explore.

Property | Specific
+FortStandard |
bFinalFort | Ends mission when destroyed if true.
bFlashing | FortStandard will flash when damaged if true.
bForceRadius | Used to make bots run for the objective if they have no backup.
bSayDestroyed | If true, bots will announce they have destroyed the objective.
bSelfDisplayed | Let the FortStandard mesh be visible. (Often set false).
bTriggerOnly | Set true to trigger the objective by touch and not damage.
ChargeDist | The distance bots will charge from if bForceRadius is true.
DamageEvent[] | Event triggered when specific amount of dmg has been inflicted.
DmgEventThreshold[] | Amount of damage needed to trigger DamageEvent[].
DefensePriority | In which order bots should defend the objectives.
DefenseTime | The amount of time (minutes) players have to complete the level.
DestroyedMessage | Message to be shown when objective is destroyed.
EndCamTag | Tag of the SpectartorCam to be used as end camera.
FallBackFort | The tag of the fort which defenders should fall back to.
FortName | Name of the objective, shown before destroyed message.
NearestPathNodeTag | The tag of the closest pathnode to the objective.
+Pawn |
Health | How much damage the fortstandard can sustain.

To actually create the assault map:
Assuming you have a design done, you can start adding fortstandards
to the level.
Place the fortstandard close to where the objective should be.
If the objective is to be triggered by touch you need to adjust correct
collision radius to make sure players can reach them, but not from too far away.
In this case bTriggerOnly should be true.

If players must inflict damage to destroy it, you must set bTriggerOnly false.
The health of the fortstandard (pawn) is used to determine how much damage
it can take before it is destroyed.
DamageEventThreshold[] and DamageEvent[] can be made to trigger events as damage increase.
When a level of damage have been reached specified in DamageEventThreshold[]
the respective DamageEvent[] is triggered.

If you want doors and other movers to be activated when the fortstandard is destroyed
you place a name in the "Events, Event" of the fortstandard and the same name,
for each object/mover to be activated, in the "Events, Tag".

The "NearestPathNodeTag" must be set to the tag of the closest pathnode to make sure
that bots are able to calculate a route to the objective.

When bots think they might not make it or you need to make sure bots run for
the objective rather than taking out defenses, you can set bForceRadius true.
ChargeDist is the distance, from the fortstandard, bots might charge from.

When the objective is destroyed the name of the fortstandard and the message will show
on the hud for all players unless the field is blank.
The message will be shown like: [FortName] [DestroyedMessage].

If this is the final objective in the map you should set bFinalFort true.

The defenders will defend the objective with the highest priority first.
When that objective is destroyed, they will defend the one with the highest priority
of the remaining ones.

The amount of time players have to complete all objectives is specified with
DefenseTime. All fortstandards should have the same value.

The endcamtag can be used to specify a spectartorcam as a view port
when the level is complete.
All players will have their view change to the spectator cam if used.

In the end this is how all objectives is created and as far as I know there is no
limit on amount of objectives you use.

 Changing the game type to AS:
UT is able to load the level in correct game type if the filename of the
map correspond with the correct game type.
In this case AS which would be AS-[mapname].unr

But, unless you do this UT will treat the map as DM and to change that
you need to set the correct "DefaultGameType" in Level Properties.
The game types are found in the actor browser under "Info", "GameInfo" and
"TournamentGameInfo".
The one for AS are found under "DeathMatchPlus" and "TeamGamePlus" named
"Assault".

 Assault Info:
To create the objective screens and text for the assault map you need to add
AssaultInfo actor, found under Info in the actor browser.
"NumObjShots" defines how many screenshots/objectives you want to show.
"ObjDesc[]" is the objective description and "ObjShots[]" contains all
the screenshots for each description.

 PlayerStarts in AS:
You need to devide the playing teams in Defenders and Attackers.
When you open the properties window for playerstarts you have a option
under "PlayerStart", "TeamNumber" which specify what team it belong to.
Use "0" for the Defending team and "1" for the Attacking team.
The option "bEnabled" can be set false/true and then triggered to become
enabled/disabled to change the spawn area/location.

 Bot AI and assault maps:
Bots defend/attack the fortstandard with the highest priority first and then
the next in line.
If you, however, use the FallBackFort to specify another fortstandard
both the defenders and attackers will treat this as the next objective in line.
In this case defense priority is ignored and might result in some weird
behaviour.

If bots is unable to reach the objective for some reason they will roam the level
like a normal DM map and pickup items along the way.

Bots tend to spend more time trying to take out the defending team rather
than completing the objectives.
In some situations this will be a problem as they never seem to advance towards the
goal.
If this is the case, set the bForceRadius true and adjust the ChargeDist accordingly.
Bots will then simply run towards the objective and hope to survive, if it
is out-numbered.

 bFinalFort true or false:
If you set bFinalFort true and the objective is destroyed, the level is
complete no matter how many objectives still left active.

If none of them have bFinalFort true all objectives must be destroyed to
complete the level (in no specific order).

 Defense Points:
Defending bots will defend the objective with their lives.
To make them stand at strategic positions you need to place defense points.
(Can be found in the actor browser under NavigationPoint and AmbushPoint).
Set the property FortTag under DefensePoint to be the same as the tag of the
FortStandard you want bots to defend.
Bots will position themselfs at these points in the order specified with the
Priority property.

If you do not have any defense points for a FortStandard bots will stand/defend
as close to the FortStandard they can get.

If you have more than one FortStandard you need to create sets of defense points
for each one.

 Spectator Camera / EndCamTag:
To create the end of level view you need to add a spectator camera.
The SpectatorCam actor is found under Keypoint in the actor browser.
Set the EndCamTag to the tag of the SpectatorCam.
This is directional so make sure it face in the correct way.
(To see the SpectatorCam in the editor you need to change view to IconView).

 Auto Cannons:
You can add TeamCannons or MiniGunCannons to support the defending team.
They are found in the actor browser under Pawn and StationaryPawn.

 Assault Randomizer:
This actor can be used to make bots take another path to the objective.
Normally a bot will always take the shortest route rendering alternative
paths more or less useless.
By placing an AssaultRandomize somewhere along the shortest route
and making sure no paths go around it you can make bots believe other
paths to be shorter than the current one.
Set the ToggleCost to a value to increase the distance cost for
that route.
(Do not set a negative value for ToggleCost).

You need a trigger to activate and deactivate this actor.


BB Drac - Unreal Tournament UED2 guide Capture the Flag explained

Capture the Flag Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

To create a functional Capture The Flag level you need to add
flagbases to your level.

You will find this actor under "NavigationPoint".

When this actor is placed you also need to adjust which team this
flag belongs to.
In the FlagBase properties under "FlagBase" you find "Team".
Insert 0 for the Red team and 1 for the Blue team.

There is also another navigation point that is used in CTF levels and
that is "AlternatePath" (also found under "NavigationPoint").

You use this to make bots able to use other routes to reach the flag.
The team that will use this alternate path is specified by
"Team" under "AlternatePath" in the properties window.
(The other team will treat this as a regular pathnode).

You are also able to adjust the "SelectionWeight" under "AlternatePath"
to raise or lower the chance of a bot selecting this path to the flag.

It is also important to know that a bot (after selecting a path to the flag)
use the shortest route to this alternate pathnode and then the shortest
route to the flag.
Make sure that the bot walks the intended route to its fullest and not change
path along the way.

 Changing the game type to CTF:
UT is able to load the level in correct game type if the filename of the
map correspond with the correct game type.
In this case CTF which would be CTF-[mapname].unr

But, unless you do this UT will treat the map as DM and to change that
you need to set the correct "DefaultGameType" in Level Properties.
The game types are found in the actor browser under "Info", "GameInfo" and
"TournamentGameInfo".
The one for CTF are found under "DeathMatchPlus" and "TeamGamePlus" named
"CTFGame".

 PlayerStarts in CTF:
You probably want players to start at different positions in a CTF level.
When you open the properties window for playerstarts you have a option
under "PlayerStart", "TeamNumber" which specify what team it belong to.
"0" for the red team and "1" for the blue team.

 Trouble shooting:
If the bots don't grab the flag even though they run infront of it, or
they doesn't seem to run towards the other teams base something is wrong.

This can in most cases be fixed if you lower the flagbase so the pathlines is
at the same height as the closest pathnode.
It might be that the bots think they are unable to "reach" the flag.

Otherwise check that all pathnodes is connected to each others so the bots
is able to calculate a route to the flag.


BB Drac - Unreal Tournament UED2 guide Domination explained

Domination Explained

By: Freddy Gustafsson aka BB Drac

bb_drac@birrabrothers.com

www.birrabrothers.com/dmain.asp

In Domination you need to add control points.

A "ControlPoint" can be found under "NavigationPoint" in the actor
browser.

When placing control points it is important that they are placed
close to the ground and not too close to each other.

Under "ControlPoint" in the properties window you have a few
attributes.
The "PointName" is the name that is displayed on the screen next
to the control point status.
The four events (red, blue, gold and green) can be changed to make
an event happen if a specific team activates the control point.

 Changing the game type to DOM:
UT is able to load the level in correct game type if the filename of the
map correspond with the correct game type.
In this case DOM which would be DOM-[mapname].unr

But, unless you do this UT will treat the map as DM and to change that
you need to set the correct "DefaultGameType" in Level Properties.
The game types are found in the actor browser under "Info", "GameInfo" and
"TournamentGameInfo".
The one for DOM are found under "DeathMatchPlus" and "TeamGamePlus" named
"Domination".


Creating Rocket Arena Maps for Unreal Tournament

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: maverick@planetunreal.com

Forward:

I decided my tutorial needed some updating, it was a little outdated and didn't have as much information as there should have been.

Abstract:

In this tutorial, I will explain how to create a Rocket Arena Map Pack for Unreal Tournament. In addition, I will explain how to create the arenas (to a limit) and what to keep in mind, as well as some other features RA: UT has.

Assumptions:

I assume you know the basics of UnrealEd, and how to load things in the Classes menu.

Tutorial:

What RA: UT is and how it works...

Alright, I will explain what RA:UT is, let's get started. A Rocket Arena map pack is a set of arenas all in the same level, each can be accessed without having to load them separately, allowing faster access between the arenas. What allows RA to have that ability is the info actor ArenaInfo, which can be found under the info class, and the special PlayerStart, ArenaPlayerStart, which can be found under NavigationPoint-> PlayerStart.

The ArenaInfo Actor

Probably the most important Actor that you will use in your RA map pack, this actor controls what type of arena the map is, how many players per arena, and the names of the arenas. It is located under Info. Here is an image of the actor's advanced options:

As you can see, there are three expandable menus under ArenaInfo: ArenaNames, ArenaTeamSize, and ArenaType. They each have a specific duty in the arena map pack.

ArenaNames: This allows you to insert a name for your arena, such as The Caves of Chizra, up until you have 8 arenas ( 0 through 7 is 8)

ArenaTeamSize: This allows you to define the number of players are allowed per team in each arena. The default is 1 and 2 players, 3 should only be used if you are planning to fight 3 bots alone, with no bot player, or you are going to play online. (The 3vs.1 bot problem is not fixed yet).

ArenaType: This defines the type of gameplay an arena will have. Multi means 1vs.1 or 2vs.2, while pickup is the Xvs.X clan arenas. To set up a clan/pickup arena, you set ArenaType to pickup, and set ArenaTeamSize at 1.

ArenaPlayerStart:

The ArenaPlayerStart is another very important Actor that you will have to use when making Rocket Arena Map Packs, They are not only used to spawn at, but to specify which arena to specify in. They are located under NavigationPoint => PlayerStart. Here is an image of one:

As you can see, there is an expandable option with ArenaNumber under it, this defines which arena you should spawn in. Remember, there is a 0 through 7 arena #, your first arena will be 0, not 1.

i.e. For your first arena, you would select all the player starts in there, then make the Arena # 0, for the second arena, do the same, but 1 instead of 0.

ArenaViewCam:

The ArenaViewCam is what allows you to view the selected arena that you are in. They are placed in an area of an arena that allows you to see most of it, and are directional, so you can aim it in the direction you want the person to see when they enter the arena.

In the advanced options, there is an expandable option with ArenaNumber under it, just like the ArenaPlayerStart. The ArenaViewCam is very similar to the APS, but you only place one in an arena.

What you want to do is make the number of the ArenaViewCam the same as the number of the arena you are in, just like the APS, and remember, 0 through 7 for arenas, 0 for the first arena, 7 for the eighth.

TastyPellet:

The Tasty Pellet is an important Actor, what it is does is gets bots to move around the map. As you know, RA maps have no pickups in them, so there are no pickups placed in the map. Well, the problem with this is that bots are based on pathnoding, they move along a set of pathnodes to get to a pickup. Without pathnodes, bots would get off course, and without pickups, there are no objects that the bots can go to and pickup, so RA uses these TastyPellets to get bots to move.

TastyPellets are literally just pickups that are invisible, and do nothing, in other words, they are duds that do not have any significant value except make the bots run to them and pick them up, without having an effect, or ammo, or anything.

When placing TastyPellets, keep in mind that you are not placing weapons. When placing TastyPellets you want a minimum of 2 pellets, and depending on the size of the arena, a maximum of about 3 for a 1v1, 4 for a 2v2, 5-6 for a 3v3, and 6-10 for a pickup arena.

Also keep in mind that you want them as far apart as possible, so the bots will run to one, then run to the next, traversing through the whole map, instead of hanging around one spot all of the time, doing little and slowing things down.

If you have Z-axis fighting, you want to place one pellet on the first level, one on the second, etc. so that they don't stay on the ground all of the time.

Thinks To Keep In Mind While Creating A Rocket Arena Map:

There are many things that you want to keep in mind while creating a Rocket Arena Map Pack, the first is Z-Axis fighting, make as many maps as you can with Z-Axis fighting. Arenas that do not have good Z-Axis support are generally boring. Good Z-Axis support generally means around two to three different levels in an arena to fight on, not too many though, or fighting and flow is hurt because you are running up and down the level to find an opponent.

The next thing you want to keep in mind is Rocket Jumping, you want to have open areas above you so that you can rocket jump. This doesn't mean eliminate 2nd and 3rd level (Z-Axis) X and Y-Axis fighting, just don't have it so cluttered that you almost always hit your head on something when you Rocket Jump.

The next thing to keep in mind is arena size. When designing an arena for 1 on 1 fighting, remember not to make it too large, this kills the delicate fast-paced gameplay, which is fatal to the fun factor of the map. Make 2v2 a bit larger, and pickups should generally be large in size. In addition to this, you want to keep in mind that you can play 1v1 on 2v2 maps, so make a lot of you maps have the ability for 2v2, just in case someone really enjoys having a team member.

You also want to keep in mind that objects on the ground are good, if used properly. When you are playing a nice RA map, and someone launches some rockets at you, then you dodge behind a freight box or something, and live, that is good placement, but when someone is launching a load of rockets at you, and every time you try to dodge, you end up getting stuck because the arena is too cluttered with objects on the ground, that is bad placement. What I am saying is that a few objects on the ground is good for gameplay, but don't overdue it.

Keep in mind that RA is a fast placed gameplay, and that your arenas should not be too dark. Your opinion of darkness may differ from that of other people, so get as many people to beta test your map for you before you release it * . This does not mean that the arenas have to be white and bright, just enough to be able to see your opponent.

One more thing you want to keep in mind is eye-candy. You want your arenas to look good, but run fast. Small effects, like lenses flares really add to the scene, and water (knee deep) does as well, but you don't want to drop your frame rates way down just because you want the arenas to look better than anyone else's. Sure, eye-candy can give you good visual points, but in RA, playability is what counts. This does not mean that you cannot have eye-candy, but that you want to limit yourself more than you would a regular map, for playability reasons.

And finally, you want to keep in mind that FPS has a major roll in RA. Using just subtracted and added brushes creates BSP cuts, which slow the level down. Use semi-solid and non-solid brushes as much as possible, correctly, since they don't create BSP cuts. Using them incorrectly can make added and subtracted brushes screw up and cause HOM (Hall of Mirror) effects and ruin a wonderful arena.

Putting It All Together:

Now that you have the arenas you want created and optimized, tested and ready, you are wondering, how do I put it all together. Well, the easiest way to do it is to have made each arena separately, then extract them and add them into one big map. The reason you want to make them separately is because it is faster and easier to rebuild, test, etc.

When all of the arenas are put into one big map, then you want to add your ArenaInfo and set that the way you want it.

Now you know exactly how to create a Rocket Arena Map Pack, have fun!

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


MultiTeam CTF 2 Beta 5

MultiTeam CTF 2 Beta 5 (Version 190) Documentation

By: Colin McCann.

wyzard@planetunreal.com

http://www.planetunreal.com/multictf/home.htm

Table of Contents

-Game Description
-Installation & Requirements
-Playing MultiTeam CTF
-- The MultiTeam CTF HUD
-- Game Options:
---- Rules
---- Rewards
---- Crazy
-- Bots!
-- Commands / Key Bindings
-Running a MultiTeam CTF Server
-Mapper's Reference
-Coder's Reference - MCTF Mutators
-Author's Suggestions and Strategies
-Author's Comments and Thanks
-Copyright / Contact Info
-Version History

Game Description

MultiTeam CTF (MultiCTF) is a capture-the-flag variant for Unreal Tournament. A whole host of new options have been added, as well as the ability to play with up to four teams!
The major difference between MultiCTF and other CTF mods is that having points is bad. Whenever you capture another team's flag, THEY get a point! The team with the lowest points at the end of the game wins!
MultiTeam CTF supports its own map type (CTFM maps), as well as regular CTF maps, CTF+ maps, and CTF4 maps.

Installation Requirements

MultiTeam CTF requires Unreal Tournament version 436. Many of the HUD features require a screen resolution of 640 x 480 or higher.

Installing MultiCTF from the UMOD version is simple: double-click on the UMOD file and follow the on-screen instructions.

From a ZIP file, unzip the following files into the following locations (where /UnrealTournament is your UT directory):

- The documentation (MultiCTF Docs.htm, all jpg files) - UnrealTournament/MultiCTF
- MultiCTF.u - UnrealTournament/System
- MultiCTF.int - UnrealTournament/System
- MultiCTFTex.utx - UnrealTournament/Textures
- CTFM-TestRoom.unr - UnrealTournament/Maps
- CTFM-TestRoomReadMe.txt - UnrealTournament/Maps

Playing Multi CTF

To set up a MultiCTF practice session, simply follow the same guidelines as starting a regular Unreal Tournament practice session, after reading the Game Options, Bots, and Key Binding sections.
Note that all of the MultiTeam CTF maps (prefixed CTFM) will be at the bottom of the map list.

There are two kinds of game modes in MultiTeam CTF -- Regular and One Flag.
In Regular Mode every team has a flag, and players must take opponents' flags and bring them home in order to give the opposing team a point.
In One Flag Mode, every team has a visible flag which CANNOT be taken. Instead, a team must find the One Flag (placed randomly thoughout the level) and bring it to an opponent's base. This gives the opponent a point.

The Multi CTF HUD

The Regular MCTF HUD

There are only two main changes that MultiTeam CTF makes to the Unreal Tournament HUD:
- The ENEMY TEAM indicator in the upper left corner. This indicates what team your bots are going after.
- If a flag is being carried, the name of the person carrying the flag is displayed in the color of that person's team above the flag's icon (on the right of the screen). If the option Omniscience is enabled, then the zone that the carrier is in will also be displayed.

Also, if a team is eliminated and can no longer score points, that team's flag's icon disappears.

The One Flag Mode HUD

In the One Flag Mode HUD, the Enemy Team display has been replaced by the One Flag display. This shows the current condition of the One Flag. If it is held, the icon appears in the color of the holder's team, and the holder's name appears over the flag. If the option Omniscience is enabled, the zone that the flag is in will also be displayed.
Also, the flag display on the right of the screen is replaced by the team symbols. If a team symbol is not present, that team has been eliminated from play.

Game Options

All of the game options for MultiCTF can be accessed by clicking on the RULES tab in the practice session window.

- Tournament, Weapon Stay, and Time Limit are the same as in regular Unreal Tournament matches.

- Score Limit - this is the point total that a team must reach before it has lost the game. If set to zero, the game will continue until the time limit is reached.

- Max Teams - this is the maximum number of teams allowed in the game. When a regular CTF map is used, only two teams will be present, no matter what the setting is here. Max Teams must be a value from 2 to 4.

To change the MultiTeam CTF rules, click on the Configure MCTF Rules button. The rules are described in the following three sections.

Multi CTF Rules

With none of the rules checked, the game will simply be a straightforward match where nothing special happens when flags are captured and nothing happens once a team has reached the score limit. In other words, teams that are above the score limit can still capture flags and be captured on.

The rules are detailed below:

- One Flag Mode - activates One Flag Mode.

- Omniscience - The zone that a flag is in is displayed above the flag. Some maps do not support this feature.

- Flag Elimination - A team that has reached the score limit will no longer have a flag! That team can no longer capture flags or be captured on.

- Team Elimination - A team that reaches the score limit is eliminated. The players can continue playing, but once they are killed they become spectators. Note that activating this will also activate Flag Elimination.

- Rejoin Teams - A team that reaches the score limit is eliminated. The players on that team, once killed, automatically join another team and continue playing. Note that activating this will also activate Team Elimination.

- Carry Flags Back - Flags must be carried back to their original position before they are returned.

- Multi-Flag Caps - Players can carry (and capture!) more than one flag at a time.

- Sudden Death Mode - Once one team hits the score limit, the team with the lowest score immediately wins.

- No Overtime - when a game is over and two teams are tied for lowest (only can occur when Sudden Death is enabled or a time limit is set), the game will immediately end. The team with the lowest score and the highest total individual Player Scores will win.

- Random Placement - Teams' positions on the map are randomized. While this can be confusing, it is helpful in keeping things fair on asymmetric maps.

- Heavy Bot Defense - bots go heavier on defense. More details in the BOTS section.

- Random Enemies - the enemy teams are randomized.

- Reward Captures - enable the rewards configured in the REWARDS menu (below).

- Enable Crazy Options - enable the options in the CRAZY menu (below).

- LMS Mode - this option only affects multiplayer games. Whenever a team is out, new players can no longer join the server as active players. Instead, they are spectators until the next game starts.

- Smart Bots - bot teams will work together if they share a common target team (detailed in the BOTS section). Bots will also not attack humans with whom they share the same target team as often - in short, teams will try to work together to put other teams out. Note that this option can lead to abuse by humans, who can often get free kills on bots that they were supposed to be working together with.

Rewards

The setup is pretty straightforward. The rows are the rewards; the columns are the number of flags that must be captured at once for a reward to be given. 'Return' means that a reward is given whenever someone returns their own flags, '1' means that someone is given a reward for one flag capture, '2' means they are given a reward for two flag captures at once, and '3' means they get rewarded for capturing three flags at once.

In One Flag mode, people who capture the flag get the rewards listed under '1'.

The rewards are self-explanatory, except for Full Health, Full Ammo, and Subtract Point.

- Full Health - this reward heals a player up to 100 health.

- Full Ammo - a player gets full ammo in all of their weapons except for the Redeemer.

- Subtract Point - the player's team gets one point taken away!

Example: If Full Health, Shield Belt, and Subtract point are checked under '2', then if I capture 2 flags at once my team loses a point, and I get 100 health and a shieldbelt!

Crazy Options

The crazy options are not recommended in most circumstances - they are mostly there just because I thought it would be interesting for a mod to have them. They are -

- Take Own Flag - Players can take their own flag from the home base.

- Flag Translocations - Players can translocate without dropping flags.

- Reward Pickups - Players who pick up a flag get rewarded as if they'd captured as many flags as they're carrying.

- Full Ammo = Loaded - players who are rewarded with Full Ammo (in the REWARDS menu) get all the regular Unreal Tournament weapons (except the Redeemer) and full ammo for all of them. This option may cause problems when using weapon mutators.

Bots!

A lot of work went into the MultiTeam CTF bots to make them play as intelligently as possible. I will attempt here to explain how the bots work. All said and done, I tried to make the bots play well so that single player games would be almost as fun as multiplayer games.

First, the Enemy Team. Bots will always go after their enemy team and just their enemy team, since having a team coordinate attacks against a single team is the easiest way to capture a flag. The bots attack the enemy team base in the same way that they do in regular capture the flag. Bot teams will select enemy teams based on several criteria, in this order:

1. If the Enemy Team has been set by a human, the bots will go after that team.
2. If Random Enemies is enabled, bots will go after a randomly selected team.
3. If there is a time limit and the Score Limit is 0, the bots will go after the team with the lowest score.
4. If Sudden Death is enabled, losing teams will go after the team with the lowest score. The winning team will go after the team with the highest score in order to get them out.
5. Otherwise, bots will go after the next team in color order.

The way the bots go after flags is the following:

- Bots go after the Enemy Team's flag.
- If a bot is close to any flag that is dropped, it will go to pick them up.
- If a bot sees someone with its own flag, it will try to kill them and take the flag.
- If a bot has a flag, its team is over the Score Limit, and the reward Subtract Point is enabled, the bot will try to get more flags so that its team can get back into the game.

Additionally, if Smart Bots is enabled, bots will not attack others carrying flags (unless they are carrying the bot's flag), nor will they attack others who have the same enemy team. However, bots will still attack humans in these conditions a little bit of the time, especially if the human attacks them. Humans should take special care to notice what teams are helping them out.

If Heavy Bot Defense is enabled, more bots will defend then normal. Normally, bots have an attacker:defender ratio of 2:1. Heavy Bot Defense changes that ratio to 1:2.

The One Flag Mode AI is a little different. Bots in one flag mode will go from base to base looking for the flag. If they get a flag, they will try to bring it to the nearest base of a team that is still in the game. If another player gets the flag and the bots do not know where it is, they will go back to base to defend against a possible attack. If Smart Bots is enabled, bots will always know where the flag is.

Commands / Key Bindings

The console commands for MultiTeam CTF are
- mutate SetEnemyXXXX where XXX is the color of the desired Enemy Team. Once set by this command, the enemy team will stay the same until changed by a human again or the Enemy Team becomes invalid (too high a score).
- mutate ThrowFlag throws all carried flags. Useful for giving a flag to a teammate so that they can capture multiple flags at once!

These commands can be bound to keys in the CONTROLS section of the main PREFERENCES menu (shown below).

Running a MultiTeam CTF Server

To run a MultiCTF server, you must have the following line in your UnrealTournament.ini file (or whichever .ini file you use):

ServerPackages=MultiCTF

Otherwise, running a MultiCTF server should be relatively easy. There are several options I suggest, however, given in the SUGGESTIONS section.

Mappers Reference

Making a MultiTeam CTF map is simple. Make a good 4-way CTF map with four standard flagbases. Then set the flagbases' teams to 0,1,2, and 3. 0 = red, 1 = blue, 2 = green, 3 = gold. Make appropriate DefensePoints, prefix the map name CTFM-, and you're set!

However, MultiTeam CTF has a number of new map objects that mappers can use to really make playing MultiCTF on their map much more interesting. The list of new objects is below. Most are also used in CTFM-TestRoom][ (which, incidentally, I made to test out and showcase the new map objects).

-MCTFFlagBase (Parent is FlagBase). A leftover from previous versions this is here simply to make MultiCTF backwards-comparible with old maps. Don't put any of these in maps.

-MCTFKillFlagZone (Parent = ZoneInfo). Whenever a flag, whether a person is carrying it or not, enters this zone the flag is automatically sent home. Useful if a designer wants to make a flag holder leave a base a certain way.

-MCTFTeamOnlyTrigger (Parent = Trigger). A trigger only activatable by the team designated, unlike the original TeamTrigger, which only can be triggered by a pawn not on the designated team. Good for team-only doors.

-MCTFTeamOutTrigger (Parent = Triggers). Much like a dispatcher, only it is called whenever the designated team reaches the score limit and Team Elimination is enabled. Useful for cutting off bases after a team is out.

-MCTFScoredOnTrigger (Parent = Triggers). Similar to a dispatcher in setup. There is an array of events, each of which is called only when the designated team reaches a designated percentage of the Score Limit. Useful to activate traps, open rooms, etc. to help a team out when it is getting scored on.

-MCTFTranslocatorInfo (Parent = Info). When this is added to a level, Translocators can be forced on or off, regardless of the server settings. Useful for levels where having/not having translocators would make capturing flags too easy or hard.

-MCTFUnblockedPath (Parent = BlockedPath) This is a pathnode that acts as a regular pathnode until triggered, at which point bots will no longer use that path. Exactly the opposite of the BlockedPath navigationpoint.

All of the original CTF objects, like Alternate Paths, Blocked Paths, and Defense Points, all work the same as before.

If and when you make a MultiCTF map, send it to me (at wyzard@planetunreal.com) and I will gladly post it on the MultiCTF page!!

Coder's Reference

The MultiTeam CTF Mutators allow greater access to gameplay than regular mutators. Look at the MultiCTF code, and subclass any mutators off of MCTFBaseMutator. The new functions are listed there, but I will paste the code here as well for reference. You will need the following line in your UnrealTournament.ini file:

EditPackages=MultiCTF

NOTE that you should NOT call NextMutator for ANY of these functions!!

class MCTFBaseMutator expands Mutator;

//////////////////////////////////
/////// Game Functions
/////////////////////////////////

// called when a team is out and when Team Elimination is on.
// OutTeam
is the team number of the team that is out:
// 0 = red, 1 = blue, 2 = green,
3 = gold
function TeamOut(byte OutTeam) {}

// Once all the accounting for flag captures is complete, this function is called.
function AllFlagsScored(MultiCTFFlag theFlag, Pawn Scorer, byte TotalFlags) {}

// when the game is over and a winner has been decided, this is called.
function GameOver(int WinningTeam) {}

/////////////////////////////////////
/////// Regular MCTF Flag Functions
/////////////////////////////////////

// called when a flag is sent home for whatever reason.
// theFlag is the flag that was sent home, OldHolder is the former flag holder.
// NOTE: OldHolder can be none!
function FlagSentHome(MultiCTFFlag theFlag, Pawn OldHolder) {}

// called when someone drops a flag. theFlag is the dropped flag,
// OldHolder is the former flag holder.
function FlagDropped(MultiCTFFlag theFlag, Pawn OldHolder) {}

// called when someone takes their own flag off of the flagbase.
// theFlag is the taken flag, NewHolder is the guy who grabbed his own flag.
function OwnFlagTakenFromBase(MultiCTFFlag theFlag, Pawn NewHolder) {}

// called whenever a flag is taken off of the base normally.
// theFlag is the taken flag, NewHolder is the person who took it.
function OtherFlagTakenFromBase(MultiCTFFlag theFlag, Pawn NewHolder) {}

// called when someone picks up their own flag off of the ground.
function OwnFlagPickedUp(MultiCTFFlag theFlag, Pawn NewHolder) {}

// called when someone picks someone else's flag off of the ground.
function OtherFlagPickedUp(MultiCTFFlag theFlag, Pawn NewHolder) {}

// called when someone returns their own flag - whether by bringing it
// back home or by touching it and returning it.
function OwnFlagReturned(MultiCTFFlag theFlag, Pawn Scorer) {}

// called every time someone captures a flag.
// If someone caps multiple flags, this function is called for each of those flags.
// Not called for flag returns.
function OtherFlagScored(MultiCTFFlag theFlag, Pawn Scorer) {}

////////////////////////////////////////
////// One Flag Mode Flag Functions
////////////////////////////////////////

// called when the one flag moves to a new postition, from either being captured,
// dropped into a damage zone, or sitting around too long.
// NOTE that OldHolder can be none!!
function OneFlagSentHome(MultiCTFFlag theFlag, Pawn OldHolder) {}

// called once the OneFlag is brought to an opponent's flagbase.
function OneFlagScored(MultiCTFFlag theFlag, Pawn Scorer) {}

// if the oneflag is dropped this is called.
function OneFlagDropped(MultiCTFFlag theFlag, Pawn OldHolder) {}

// when the oneflag is picked up, this is called.
function OneFlagGrabbed(MultiCTFFlag theFlag, Pawn NewHolder) {}

For examples on how these functions are used, look at the MultiCTF Mutator Pack that I released (on the MultiCTF Home Page).

Author's Suggestions and Strategies

After LOTS of playtesting, coding, answering questions, etc. I have a pretty good idea of how this mod works in most situations - and what to do if you want to win.

The KEY factor is defense. By not telling your bots to defend, the first few bots on your team will go on offense, leaving nobody at home guarding the flag (if you go on offense). Not good. Make sure someone stays at home at all times. If you have lots of points, up the number of defenders on your team.

Another important thing to remember is picking the best Enemy Team. Keep in mind what options are on - Flag Elimination, Team Elimination, etc. If you can get a team off of your back by scoring on them, do it!

While throwing flags may not seem too important, it has three good uses:
1. Giving a teammate (who also has a flag) another flag. He can then get the reward for more than one flag - PARTICULARLY important if Point Subtraction is on!
2. Throwing your flag off of the map. If carry flags back is on, and you're on Face 4 and you're not gonna make it back to base to return your flag, ensure that it goes home by tossing it over the edge. Jumping off works too, but sometimes you can't even make it that far before being gunned down.
3. By throwing the flag somewhere inaccessible or hidden, you can protect the flag for 60 seconds (until it is automatically sent home). Also, you can do 'short translocations' by throwing the flag up somewhere and then translocating and grabbing the flag. Handy.

Keep it in mind if Smart Bots is on - if so, don't kill bots just because they're on other teams! They'll help you get out a common enemy.

For servers: I personally like relatively quick games. I often set a time limit between 5 and 10 minutes and a Score Limit of zero to keep games quick and simple. Remember that in online play people want to be playing most of the time, and that epic struggles games aren't fun every game. So keep the score limit not too high. But this is my suggestion, do what you will!

My favorite options to have enabled are the following:
Smarter Bots, Carry Flags Back, Multi-Flag Caps, No Overtime, Random Enemies, and Reward Captures (I have the rewards set up the way they appear in the picture in the Rewards Section). These are my personal preferences, but of course anything goes!

Author's Comments and Thanks

MultiTeam Capture the Flag took about eight months to develop fully, and lots of hard work on my part. This is basically a one-man mod! The feedback and interest I have recieved have well exceeded my expectations. The UT community is great! I hope you greatly enjoy the mod. MultiCTF was built for fun - try using all of the options and see what kind of games you can play!!

And now, here are all the cool people who beta tested for MCTF! Without these guys' input, MultiCTF would be absolutely nowhere. My personal thanks goes out to:

Ace_3000, Action Hank, Agent248, Agent Orange, Area 51, Berzerker, Bretai [DPW], Chris Pandolfo, Ciparis[FAT], Csuthy Andras, Dark Defender, Dirk Forsterling, Disposable_Hero, Donald Noordt, Ebonite[DPW], E.R.N., Farid Hamidouche, Goyim_Smasher, Hamburger_Pimp, Hendrik Vermeylen, jAcKhAmMeR, Jay, Jeffery Russel, Jim Montz, John Phillips, Josh Spencer, Kim Gellet, Keith Malinowski, Leigh Makewell, Lister of Smeg, Ludovic, MADMAXQUINN, MarczoiereY, Menno Lodder, milliByte, Moo, Nero, Nightmare, Nina Batina, Nocrutis, Pazarius, Qaisar, Rene Jacobson, Ronald Steinkellner, Schnieder Alexander, Sean Sexton, [ZB]_Sephiroth_, {BIO}Solomon, Spicy, The_Stranger, TechnoArcher, Telarium-Y2K, Tolle, Toter, Wing_Zero, Zan .

Here are the great mappers who made MultiCTF maps:

CTFM-Ancient, CTFM-BurningHot, CTFM-Random, and CTFM-Small: Death Circus
CTFM-Catacomb and CTFM-GlassBang: Jasper 'Weenydog' Lodder
CTFM-CruxCitadel and CTFM-CrystalPower: The Shadow
CTFM-CrypTitan: TheSpoonDog
CTFM-Deck16][, CTFM-HyperBlast, and CTFM-Mazon: _Lord'Coloth
CTFM-FireIceSlimeBullet: [DMF]ABU5E
CTFM-InstaMayhem: [MK]Annihilator (wherever you are)
CTFM-Lavaforme, CTFM-MorTal, CTFM-Tutorial][, and CTFM-SlimeRotor: Crokx
CTFM-LavaGiant][: Dark Defender
CTFM-MetalDream: Rens2Sea
CTFM-Sphere: SlayerA

Thanks, Bob-Dog, for some MCTF textures!
Other textures in the MultiCTFTex.utx package were compiled from the levels mentioned above - each texture there is prefixed with the name of the level it was originally packaged with.

I also gotta give mad credit to UCLASSES, UMODWIZ, and EMACS for helping me out in the creation process, and the boyz at PLANETUNREAL for hosting my site.

If you think you deserve credit and you were left off of this list, email me and tell me what's up!

Copyright and Contact Info

The MultiTeam CTF homepage is http://www.planetunreal.com/MultiCTF. Stop by anytime!
Please send anything MultiTeam CTF related - questions, maps, mutators, comments, suggestions, etc. - to wyzard@planetunreal.com and I will get back to you A.S.A.P!

And now, the copyright stuff...

This gametype is Copyright 2000 / 2001 Colin McCann.

Authors may NOT use this game type as a base to build other game types, nor are they allowed to commercially exploit this gametype, i.e. put it on a CD or any other electronic medium that is sold for money, without my explicit permission.

You MAY (please do!) distribute this game type through any electronic network, provided you include this file and leave the archive intact.
MultiTeam CTF has been tested on a variety of systems, but it is provided as is. The creator of MultiTeam CTF (that's me) assumes absolutely no responsibility for anything that happens to a user's system while running MultiTeam CTF.

You MAY have fun with the game!!

Unreal Tournament (c)1999 Epic Megagames, Inc. All Rights Reserved. Distributed by GT Software, Inc. under license.
Unreal Tournament and the Unreal Tournament logo are registered trademarks of Epic Megagames, Inc. All other trademarks and trade names are properties of their respective owners.

Version History

MCTF2 Beta 5 (Version 190):
Release Date: February 10, 2001
-Made the menus prettier.
-Further improved smart bot target selection - now bots will rarely attack friendly humans on other teams.
-Subtract Point works like other rewards
-Fixed a bug when MaxTeams = 3
-Now thrown flags go in the direction you're facing
-Take own flag always works RIGHT
-Fixed a bug where teams with nobody on them could win
-Changed back to not being able to see a score if nobody is on a team
-Improved Messaging
-Fixed KillFlagZones leaving flags in limbo if holder had multiple flags
-Added 'Omniscience' option and ability to see flags' locations
-Made the scoreboard better
-Fixed a bug with LMS Mode in single player
-Added support for new MCTF Mutator functions
-Fixed OneFlagMode AI for TeamScore = 0
-Took MCTF-Testroom][ out of the MultiCTF package
-Combined more textures into the MultiCTFTex.utx package

MCTF2 Beta 4 (Version 180):
Release Date: December 10, 2000
-The name of someone who has the flag is now displayed over the flag in the color of their team.
-Fixed Take Own Flag / Reward Returns bug (Thanks Zan)
-Spectators of eliminated teams can now see from anyone's point of view
-Added rejoin teams option
-Added MultiCTF Mutator support
-Fixed a bug where flags were being sent home multiple times
-Fixed HUGE bugs when the Score Limit was set to 0 (thanks Rene Jacobson!)
-Improved One Flag Mode AI
-Added Score Subtraction under the Rewards menu
-Fixed a bug in LMS mode - now if all humans have left the game, the game restarts. (Thanks Ciparis[FAT])
-Changed "Omniscient Bots" option to "Smart Bots" - and changed the AI accordingly.
-Added No Overtime option.
-Added Random Enemy Team option
-Fixed other minor bugs.

MCTF2 Beta 3 (Version 170):
Release Date: November 26, 2000
-You can now see multiple flags on people who have more than one flag!
-Fixed a 'feature' where if you had Take Own Flag and Reward Pickups enabled that you could take your own flag and get all beefed up with rewards. (Thanks Goyim_Smasher)
-Started giving credit to the people who've helped since version 1! Sorry for not doing it sooner guys!
-Changed the MultiCTF map prefix from MCTF to CTFM.

MCTF2 Beta 2 (Version 160):
Release Date: November 17, 2000
-Completely did away with the necessity of the MCTFFlagBase class.
-Maps can now have less than 4 flags and everything should be fine.
-All the messages now work correctly!
-Bots now return their own flag right away!
-Added a little 'recognition' system to the scoreboard displaying who has the most frags, flag kills, flag captures, and flag returns.
-Added the MCTFUnblockedPath class so now mapmakers can block paths and the bots understand it.
-Added a new crazy option: Full ammo = loaded.
-Added Heavy Bot Defense option.
-Added LMS join option.
-Really souped up the rewards menu.
-Got rid of the MCTF with CTF maps gametype.

MCTF2 Beta 1 (Version 150):
Release Date: November 10, 2000
-Added new menus all over the place.
-Added about 10 new game options
-Added the option Single Flag Mode.
-Added support for CTF, CTF+ and CTF4 maps with the new Gametype MCTF with CTF maps.
-Further improved Bot AI.

Version 115:
Release Date: October 21, 2000
-Official release version of MultiTeam CTF.
-Added code so now bots will pick up any flag if they're close enough. Should greatly improve bots' actions.
-Added code so bots will not particularly go after people on other teams who have flags that are not the bot's enemy team's. (If that makes sense).
-Added code so that TeamOutTriggers are triggered if a team is not in a game (e.g. the Gold Team's MCTFTeamOutTrigger is triggered at the beginning of a game with only three teams).
-Finished MCTF-TestRoom][!

Version 110:
Release Date: October 13, 2000
-Added a MultiTeam CTF Tab to the Unreal Tournament browser window.
-Changed the MCTFTrigger types to work all the time now... (I hope)
-Other minor fixes to the code

Version 100:
Release Date: October 1, 2000
-First release of MultiCTF online!


Prefab Textures

By:Rewind

rewind@planetunreal.com

http://www.avidgamer.net/

Tutorial:

This is another one of my "prefabs for dummies" tutorials... This one should help even the most challenged of you get your prefabs looking just like the screen shots!

 Pick a prefab (I used the Cargo Pallet for this example). Next, make a good sized room (if you are following me make it 512 all). Texture the room any way you want and add light. Now BEFORE you add the prefab, load ALL the texture sets that it requires. The textures used are usually stated in either the Read me of the prefab or in its description. The texture set for the Cargo Pallet is SkyCity.utx

Now after ALL the required texture sets are loaded, add the prefab to your level. Then just rebuild geometry are you have your prefab!

here are some things you need to know about prefabs and textures...

1. You must ALWAYS load the textures BEFORE the prefab or it will not be textured correctly.

2. Some prefabs do not have their textures listed. For these prefabs just load every texture set UnrealEd has. The editor will automatically filter out the ones you do not need next time you save your level.

3. Some prefabs have custom texture, make sure to unzip these to your Textures directory and load these.


Prefabs Made Easy

By:Rewind

rewind@planetunreal.com

http://www.avidgamer.net/

NOTE: This tutorial (like every other tutorial at Prefab Central) assumes that you have at least a basic knowledge of UnrealEd.

Tutorial:

Ok, all you people who email me 5 times daily asking this stuff had best be reading! This my all-purpose "Prefabs for dummies" tutorial. Its for all you people who just can not load those prefabs! First off, you will need to download a prefab (really?)... Any will do. Unzip it to some directory you will remember. I use \Unreal\System\3ds but you can use whatever you want. Then start up Unreal Ed. Now subtract a simple little square room (I used 512x512x512) and texture it any way you like. Now add light, a start location, and rebuild the geometry (F8). Next you will need to load whatever textures the prefab uses (unless you want to texture it yourself for some reason). NOTE: If you do not load ALL the textures the prefab requires it will NOT be textured when you import/load it!

Now for the fun part, importing/loading the prefab to your level! Look at the prefab you downloaded (in Windows explorer or whatever). If it has a .t3d, .dfx, or .asc extension you will want to import it to your level. If the prefab has a .u3d extension you will want to load it to your level.

LOADING A PREFAB

Ok, so you want a .u3d prefab in your level. Go under "Brush" on the UnrealEd menu and select "Load" (or press Ctl-B).

Now just select the prefab you want to add your level and click "Open". Since you are loading the file and not importing it, the brush of the prefab should simply appear in your level. Move the brush to where ever you want the prefab in your level and add it!

IMPORTING A PREFAB

Importing a prefab to your level is a little more difficult than simply loading one, but it is still really simple. To start, just go under "Brush" on the UnrealEd menu and select "Import".

Now go to the directory where you saved the prefab, select it, and click open. A menu (like the one below) should pop up. Unless the prefabs read me says differently, you should leave all the options on their default settings.

You should see a brush of the prefab. Move the brush to where ever you want it in your level and add it!


Making Prefabs with UnrealEd

By: Gusher

In this tutorial we will cover how to make a BASIC prefab.

1. Open UEd, and subtract a cube (as big as or as small as you like!)

2. Decide what you are going to make.

3. Make it out of brushes, this is what mine turned out like:

4. Size the red builder brush so that it covers the ENTIRE prefab, like this:

5. Now go to the top menu and select "Brush" then select "Intersect."

6. The red builder brush should have surrounded the prefab you made out of normal brushes like this:

7. Now click "Brush" on the top menu again and this time click "Export" you should be presented with a window like this:

8.Pick a folder where you want to save it, don't change the file format though, leave it as ".t3d" file format, click save and your done!!


Using Qool for Unreal Prefabs

By: Jim 'Willy Survive' Nobels

jnobles@multipro.com

Willy Survive Website

This small tutorial is for those people who use the quake and quake2 level editing program known as Qoole and who have become interested in creating maps in UnrealEd.

The problem is that we’ve become used to Qoole’s ability to edit the vertices, edges and faces of a brush in order to make any 3d shape we want rather easily but UnrealEd’s brush editing functions are rather limited compared to what we’ve become used to. At least as of Unreal version 2.20 the vertex editing capabilities are far less than what would be desired. Maybe that will change with a later version but until then...

This article is about using Qoole to create 3D brushes that UnrealEd can import and use.

BSP2T3D written by Jeff "Pointdexter" Preshing is an excellent little DOS utility that will take a small Quake (NOT Quake2) map and convert it and its components to brushes in the .t3d format that UnrealEd can import. Here’s a brief description of its capabilities taken directly from its readme file:

1. Get a BSP file for Quake. For example, foo.bsp

2. Run Bsp2t3d on this file with the -a option. After running this, You should find a few .t3d files in the directory you ran it from.

Example:

Bsp2t3d -a foo.bsp

...would create the files foo000.t3d, foo001.t3d, foo002.t3d, etc. The first file, foo000.t3d, caontains the main brush of the entire level. Each of the other *.t3d files come from other entities in theQuake map, like lifts and doors.

3. Create a new, empty level in UnrealEd.

4. Select Brush->Import from the menus. Import the first file, in this case foo000.t3d. For the import options, choose Nonsolid and Keep Original Polygons Intact.

5. After it loads, subtract the brush from the world.

Now I’ll give you a few tips...

Don’t try to use BSP2T3D to convert entire maps. No matter how small they are. Learn to use UnrealEd to create your maps and use BSP2T3D to create prefabs to be added into that map. And then only use it for those prefabs that you feel are so difficult to make in UnrealEd that the situation demands that you find another way. BSP2T3D is a utility, not a crutch. On the other hand, you might have a bunch of old quake prefabs just taking up disk space that you might like to see used in your Unreal maps...

BSP2T3D needs a quake .bsp file to work with. The only way I could get Qoole to output a quake .bsp file was to re-install quake on my hard drive. I’ve been told that there are ways around this but I couldn’t make it work any other way. If you figure out a way to do it without having all of Quake installed then please let me know, especially if you are using Qoole.

Maybe you are using an editor other than Qoole that doesn’t require quake to be installed in order to output a quake .bsp file and that’s fine. It doesn’t matter which editor is used but only that a valid quake .bsp file is produced.

Since a valid .bsp file is needed that means that your prefab needs to be part of a valid map, in other words, it has to be part of a closed map with no leaks. And the map will have to have a Player Start entity in it. The best way to deal with this is to design a big open room and put a Player Start in it. This will be your workshop. You don’t have to put any lights in your workshop unless you want it to look pretty in case you decide to look at your prefab from within quake. In this workshop you will build your prefab. Preferably up in the air where it doesn’t touch the walls or floor or ceiling.

Now here’s an important tip:

BSP2T3D will create separate 3d brushes for the entities (except for the Player Start entity which is apparently ignored.) Therefore you can build your prefab and then GROUP it then apply an entity function to that group and it will be converted out as a separate file and not as one big 3d brush which includes everything including the walls, floor and ceiling. This is a very useful function because otherwise you’ll end up with the entire map as a 3d brush and you’ll have to get your prefab out of it once you get it into UnrealEd. I did it this way several times before I bothered to read all the instructions that came with BSP2T3D.

Here’s how it breaks down:

In Qoole I made a map with a large room and a Player Start entity in it. I built my prefab in the center of the room and then grouped all the parts of my prefab together. See the pictures at the top of this page for reference.

I then assigned that group as a door entity. I didn’t mess with any of the door variables as they were irrelevant to the process. I then compiled the map as PYLON01 which produced the PYLON01.BSP file which was placed in the quake\id1\maps directory.

Then I opened a DOS window and went to my unreal\qoole\work directory where I keep BSP2T3D and copied PYLON01.BSP into it. BSP2T3D is a DOS program so you have to work with it from within a DOS window. Did I mention that?

note: It would sure be nice if someone would write a nice smart little Windows Graphical Interface for BSP2T3D. It would make it a lot easier for newcomers to use.

Once I got PYLON01.BSP into my unreal\qoole\work directory (folder) where BSP2T3D is located I typed in the following:

bsp2t3d -l pylon01.bsp

and the following information was displayed:

See if you can figure out what it means...

Here’s a major hint:

Model # 0 is the outer structure which includes the walls, floor and ceiling. Model # 1 is the pylon prefab which was dealt with separately because it was assigned as an entity. If the prefab had not been assigned as an entity it would have been considered part of the structure. Then there would have been no model # 1 and I would have had to get my prefab out of the whole workshop brush (model # 0) after I’d imported it into UnrealEd. It can be done that way but it’s a bother. It’s better to make your prefab an entity so that it can be dealt with separately from your workshop structure.

Be sure that you don’t assign your prefab as an entity until you are through adding stuff to it. If you add stuff to the prefab after it’s assigned as an entity the new stuff will probably be considered part of the structure and won’t be included in your prefab model. If you add stuff to your prefab after you’ve assigned it as an entity then group the whole thing together and assign the new larger group as an entity (producing an entity inside an entity) unpredictable results could occur. That means I haven’t tried it so I don’t know what will happen.

At this point no actual 3d brushes have been produced. All the ’bsp2t3d -l pylon01.bsp’ command did was give me a list of the models that could be found within the PYLON01.BSP file. Since I was only interested in my prefab which is model # 1, I typed in the following:

bsp2t3d -e 1 pylon01.bsp

And here’s what happened:

The -e parameter tells BSP2T3D which model I want to extract. -e 1 means that I only want model # 1. So that is the model, and the only model, that was extracted. I wanted to make sure my model (3d brush) was really there so I checked by using DOS’s dir command.

Yep, it’s there. And it’s named PYLON01001.T3D

note: if you simply type BSP2T3D in the DOS window you will get a list of parameters that BSP2T3D can do things with.

Now that I had my new 3d brush I imported it into UnrealEd:

It worked! There it is in red. I imported it as a solid rather than as a non-solid that Pointdexter suggested in the readme file. I simply couldn’t figure out a reason why it should be a non-solid. At least not for my purposes.

Email me if you have some general questions about the process. If you have technical questions about BSP2T3D you will probably be better off emailing Pointdexter as I don’t know how BSP2T3D works. I’m just learning how to use it. If you have questions about how to go through this process with Qoole I can probably help you. The same with how to import these models into UnrealEd. If you have questions about how to use this process with other .bsp editors then I probably won’t know the answers as I’ve only used Qoole.

By the way, Qoole 2.50 is shareware and has a limit of 300 brushes until registered. The pylon in the picture above is made up of four (4) brushes. Qoole 2.50 is currently available for download from the Qoole web page but it will be gone Very Soon as there is a new version now in final beta testing. But 2.50 is more than adequate for what we’ve been talking about here.

If you use this process with an editor other than Qoole then perhaps you will do a write up on how it all works using your editor... If you send it to me and it is presentable I will post it on this page so it will help others who are using the same editor. You get the credit.

© 2001 Matt Cobb Designs


UT Kickers

Creating and Adding Bot Support For Jump Pads (Kickers)

By: Sam Sutton

sutton@alphalink.com.au

Audience: Level Designers

In this tutorial, I will show you how to make a jump pad that works for humans and bots, plus how to add a sound effect.

Jump pads, (or kickers) work in a very similar way to lifts. They require two lift exits, a lift center (found in the NavigationPoint section of the classes browser), and a kicker, which is found under the Triggers section of the classes browser.

There are two main types of kickers – vertical ones, that kick you up, such as in DM-Morpheus, and DM-Cybrosis][, and there are horizontal ones, that kick you up and across. If you are familiar with Quake III: Arena, they are in almost every level.

Setting up a kicker

The kicker actor, is for the moment, the most important part of making a jump pad work. This is what moves you from position A to position B. Open up the properties of a kicker, and expand the Kicker tab. There are four sections in it: bKillVelocity, bRandomize, bKickedClasses, and bKickVelocity.

KillVelocity is the most important attribute of a kicker, and of all the custom levels using jump pads that I have seen, none of them have set this attribute to true.

Basically, KillVelocity stops you (and bots) from being thrown off in a random direction. What it does is this: it ignores any existing velocity that you had before making contact with the kicker. So if you run at it at an angle, drop down from above, walk onto it, or run onto it, you will always land in the same place!

There is only one slight exception. After much experimentation, I found that if you run at a jump pad, and jump onto it, you will get kicked a little bit further than if you just run at it and don’t jump. However, this is only a marginal amount, and will only matter if you have a jump pad that goes to a very small platform – you may fly over it.

So KillVelocity is a must for horizontal jump pads. For vertical jump pads, KillVelocity is not essential, but it is better to use it anyway, for the bots’ sake, as they can’t use air control as well as humans.

Randomize is set to false by default, and I would leave it at that – I don’t know what the point of it is.

KickedClasses is just who can use the kicker. The default is pawn, which means anyone can use it, so leave it at that.

KickVelocity has 3 components – X, Y, and Z. It is here that you plug in the values so that you can get to your destination. X is horizontal (north ß à south), Y is horizontal (east ß à west), and Z kicks you up, (or down if you desire!).

If you have all 3 components set to 0, you won’t go anywhere. A positive value sends you in one direction, a negative in the opposite. In the case of Z, a negative value will kick you downwards.

For a simple horizontal kicker, you will need either X or Y, and Z. If you don’t have any Z value, you won’t go very far. It depends on how far you want to get kicked, but you will probably need at least half the horizontal component in Z. Over long distances you may need more than the horizontal component. Getting the values right takes a lot of testing and guessing, so be patient. Make sure you set you KillVelocity to true first.

For a more complicated horizontal kicker, you may want to be kicked at an angle. In this case, you will need both X and Y components, as well as Z.

For a vertical kicker you could just have a Z component, which will kick you straight up, and you can use air control to get to the ledge or whatever. However, I recommend adding some X (or Y, depending on the direction) so that it steers you slightly in that direction. The reason is bots (always is!). If you just have a Z value in you KickVelocity; the poor bots keep bouncing up and down until they are "helped" by some flak or a rocket!

There is one other thing you will need to change – the collision radius. The default is 40, and for a jump pad of size 128 units wide, by 150 units long, this is not enough. If you set it to 80, it should be ok. You can change the collision height too if you want, but you will only want to change it for a vertical kicker. Collision height is how far away (vertically) that you have to be to trigger the kicker. The only reason for changing it is it looks funny if a bot, or player is kicked from above the actual brush (it looks like they are bouncing from thin air). It isn’t much of an issue, but changing it to 20 or smaller will fix that. Just remember that changing the collision height affects how high you are kicked, so if you make it smaller, you will want to make your Z value bigger.

Adding Support for Bots

As I said earlier, jump pads work in a similar fashion to lifts. Make sure that the lift exits, and lift center all have the same LiftTag.

Put your lift center where the bot will "get on" the jump pad – in the middle of the brush, next with the kicker should be fine. Place one lift exit where you want the bot to "get off", but out of the way a bit, just as you would do for a lift.

The other lift exit needs to be placed before the jump pad brush, also as you would do with a lift.

Adding a sound effect

To do this, all you need is a trigger, and a special effect. Open up the trigger properties, and open the event tab, and set the event to something like jumpsound. Now go to the trigger tab, and set initiallyactive to true, and the triggertype to playerproximity.

Now open the special event’s properties and open the event tab, and set the tag to the same thing as the trigger’s event. In this case: jumpsound.

Note: If you have more than one jump pad in your level, make sure your event and tag of your trigger and special event is different for each one.

Now go to your browser and open SoundFX. Click on the first dropdown menu and select Unreall. Click on the next dropdown menu and select Pickups. Now click on the sound BootSnd. In your special event properties, expand the SpecialEvent tab, and down the bottom where it says sound, click on it, and hit Use.

Also, alter the collision radius and height of the trigger and special event so that it is the same as the kicker’s, and try to place them in about the same place and at the same height as the kicker actor, because otherwise the sound won’t play consistantly.

Bot Bugs

There are a couple of bugs that need to be brought to attention. Bots tend to jump higher than humans on kickers, and on some angled jump pads, if the angle isn’t very steep, the bots seem to interpret this as flat, so they will bounce straight up in the air first, then jump horizontally. This is a problem with UT AI, not your kicker.

Conclusion

Jump pads are not difficult to make, but to get them to work properly, consistantly requires some effort. Bots, as with most things are quite tricky to get exactly right, and you will most probably have to play around with the locations of the two lift exits.

If you want to see a level that has complete working jump pads in it, go here . If you have any problems, you can always email me.


Creating HUDs for UT

by: Cralex NS
cns@planetunreal.com

How to make HUDS for UT

(Note: I hope you can understand if not ICQ#91846003 me. This tutorial is for experienced PSP users)

So, we want to make a HUD for you mutator or mod, huh? Ok I`ll try to guide you though how to.

Let`s start out with the sizes..
If you want to make a Crosshair it should be 32x32
If you are making a HUD part ex: health icon, it should be 64x64
Scopes are 256x256 rescaled..
Everything else, like menus and stuff, should just be so it fits best into the scaling numbers.

1. Making the HUD icon.
(Paint Shop Pro)
Let`s make a Health Icon, shall we?
Start out with creating a new image 64x64 GreyScale Background: Black
We are making a Grayscale image because UT can color the HUD icon it self, red blue yellow etc. (Coding Stuff)

Paint a Cross or what ever you want.

Here I made a simple template, to get it all aligned right.
That is very important that one of the sides are not longer then the other, cause that will look very bad, unless you want it that way

Now Make the final shape of your Health Icon out from your template

Big Jump, I made my shape a bit tech like? and added different colors hmm? why, you say?
Well, darker colors will also be darker red or what ever color you color it in UT, so you can actually make 3D like HUD :)>

Now TO make it look less raw, we could add some filters, PSP got everything we need!

Ow? Yeah, now it doesn`t look that raw more, and it got a nice feeling to it. How..
First I added some lightning, and then I Gaussian Blurred the HUD 0.50
Its finished, now you can fuck around with it just keep in mind everything black is full-transparent everything else is semi-transparent.

A little Demonstation:

I colored it with PSP, and made it transparent (75%) it will look a bit different ingame though! Again depending on the coder.

2. You want it in Game.!
First of all make sure your HUD is 16x16, 16x32, 32x32, 32x64, 64x64 and so on, make sure if its a HUD icon, that it is Greyscale.
Now Importing is a whole different manner, if your making a mod you should give it to your coder of course, if your making a mutator on your own
I would goto http://www.planetunreal.com/wod/tutorials/make.htm a good tutorial on importing using the -unreal make.
Advanced Mappers or Coders can do this :)

tutorial by Cralex NS - cralle@wanadoo.dk


Creature and Thing Factories

by: HolySmoke
holysmoke@erols.com

Forward:

Creature and thing factories are a great way to add a little excitment to a level. What better way to surprise someone than to have a Skaarj attack from behind when you know there was nothing there a second ago. Or to leave an empty room only to return to find a couple of Krall standing there waiting for you.

Abstract:

Factories are simple, but you have to know a couple of little secrets

Assumptions:

I assume nothing but that you have a basic knowledge of the editor

Introduction:

Creature and thing factories may be triggered by a trigger whose event equals the creature factory’s tag, or will trigger themselves if a player touches it. Since zone changes can cause an event, you could for example cause a creature factory to start producing razorfish as soon as a player enters the water. The first creature spawns instantly. Creature and thing factories use Spawnpoints ( a type of navigation point) as the locations to create actors. Up to 16 spawnpoints can be associated to a given factory. Spawnpoints and creature factories are associated by giving them the same tag. If a Spawnpoint has a tag in its event field, that event will occur when a creature is spawned from that spawnpoint. By default, creature factories are covert, which means they will only spawn actors at a spawnpoint no player can see. A creature from a factory has its event set to the factory’s tag (so its death will trigger the factory).

Tutorial:

Ok.. lets start by building two large rooms with a connecting hallway. put in some lights so you can see and add a player start in one room. Now place a creature factory in the hall where the player will be sure to walk through it.you can find it in keypoints. Make the tag anything you want. Set the prototype to the kind of creature you want it to spawn. Now place a spawnpoint where you want the creature to spawn,These are located in navagation points. Set the tag the same as that of the factory.

now rebuild and try it out. you"ve now built a creature factory

Thing factories work pretty much the same way but spawn items like wepons ,ammo health and the like. Experiment with the properties and figure out alternate ways of triggering them.

Thing and creature factory properties are:

1.AddedCoopCapacity: Extra items to produce if the game type is CoopGame.

2.AlarmTag: (Creature factory only) AlarmTag given to creatures produced by this factory.

3.Orders: (Creature factory only) Creatures from this factory will have these orders

4.OrderTag: and ordertag. By default they will attack the instigator of the factory.

5.event:anything you want

6. tag:again any name you want,(this name must be the same for both the factory and the spawnpoint.

7.bCovert: Only do hidden spawns (true by default for Creature factories, false by defaultfor thing factories).

9.bOnlyPlayerTriggered: Only a player can trigger this factory (true by default).

10.bStoppable: Stops producing when untouched.

11.Capacity: The maximum number of actors this factory can ever produce (-1 = no limit).After reaching this limit, the factory shuts down.

12.Interval: The average time interval between spawns.

13.ItemTag: Tag given to items produced by this factory.

14.Maxitems: The maximum number of active actors from this factory at any time. If it is a creature factory, new creatures will only produced either initially, or when a creature dies, to get back up to maxitems until the factory capacity is reached.

15.prototype: The class of actors produced by this factory.

16.TimeDistribution: The distribution of the interval between spawns.

DIST_Constant - constant interval (always equal to Interval).

DIST_Uniform - uniform interval (random time between 0 and 2 x interval)

DIST_Gaussian - Gaussian distribution, with mean = interval


Monster Properties

by: Marc EG Gravett
marc@avatar.co.uk

In this tutorial/document I"ll be taking you through some advanced features of the Monster/Creature Properties. Included HERE is the Sample Map.
I take it you know how to make a room with lights and you know how to place monsters/decorations etc. If not then I suggest you check out some of the Basic UnrealED tutorials that are available on the "net.

Roaming Monsters/Creatures

Make a nice large room with a high ceiling (important for later on) and put the lights in and texture it how you want. Now place your playerstart in a corner. Place a lovable NALI in the center of the room, right click and select his properties.
Go down to +Orders then put bFixedStart to FALSE, in the Orders box write in "Roaming" (without the quotes!!!) and thats it.
"Wandering" also works but I hav"nt found a difference between the two if there is one. Compile your level if needed and play, what you will now see is the NALI walking around without the need of patrolpoints. EVERY monster/creature can do this so it adds a great replay level to your maps.

Bigger Monsters/Creatures

When you"ve got over the exitement of seeing your NALI walking by himself, hit CTRL+W to duplicate him, then do this:
Open his properties and go to +Display, go down to where it says DrawScale. You will see it says 1.000000 - change that to 2.000000. What this does is makes the NALI 2x bigger, you can put any value you want, make him smaller or bigger (I made a Skaarj 20x bigger....now that is scary!!!) - but for now just put in 2.000000.
Now when you play the game you"ll see he is 2x bigger.....BUT.....he is still moving at the same speed as if he were the normal size, so go back into UED.
Open up his properties and go down to +Movement, in here you"ll find all the air/land/water speeds that need to be changed.
Now this is fairly simple, we made the NALI 2x bigger so therefore most of the things in +Movement need to be doubled -
here is a list of what needs to be changed and what it should be changed too: (you dont need to put in all the 0"s, just the digits before the . are good enough)
AccelRate from 900.000000 to 1800.000000
AirSpeed from 320.000000 to 640.000000
GroundSpeed from 300.000000 to 600.000000
MaxStepHeight from 25.000000 t0 50.000000
The other things may be needed but are not that important right now, more exploration with them will show you what they do.
Basically what we just did was to tell the NALI that he"s been made bigger so therefore he needs to walk like he"s bigger. For example the GroundSpeed keeps the animation of the NALI walking to match his overall size, so it does"nt look like he"s skating or walking dead slow for someone so big. You can of course make him smaller, say the DrawScale of 0.750000 - but then the AccelRate/GroundSpeed etc need to have 25% taken off so it keeps to the animation of the Nali properly. Otherwise you get a small NALI walking around dead fast!!!
Experiment with other creatures and see what you can do with them, a 40x bigger NaliRabbit is cool, or how about 3 smaller Krall all being lead by a Bigger Krall.
Other Stuff
In your selected monsters properties go to +Display and down to Fatness, this changes the overall fatness of the desiredmonster, i.e. Make NALI"s thinner and COW"s fatter.

If you make a Bigger/Smaller creature/monster then go down to +Pawn and make them Stronger/Weaker in the Health box, give them something to drop when killed, change their Field Of View so they can see behind themselves :)

Various monsters have different attributes you can change, for example:
With a Skaarj you can change the amount of damage he does by going to +Skaarj in his properties, from here you can also have him Fake Death and push buttons. In the above +Combat area you can change his RangedProjectile by doing this:
go to the Scripting window on the right side of UED, and expand the Projectiles area, select anything you want....say the
Arrow, then in RangedProjectile hit USE, now your Skaarj will attack with an Arrow when he"s firing from long range.

In Conclusion

I have only scratched the surface with the Monster/Creature properties, fiddle around with them yourselves and see what you can come up with.....and all of this without having to do ANY scripting. What this also adds is great replay value to Unreal single player levels. You may well play on level where Skaarj are twice as big, where Brutes fire BioGel instead of rockets, where every Monster roams the level from start up making the same level play differently every time you play it. The Decorations can also be made bigger/fatter - plus everything can give off sounds and lighting.....the best thing to do is experiment with UED and find all its hidden secrets.

If you have any questions or comments then feel free to write to me at the above address. Have Fun :)


Patrol Points

by: Dafred
dafred@dalnet.se

When writing this tutorial I assume that you can handle the basic interface of UnrealEd, know how to build a basic room and tweak the preferences of Actors. You need to know these things to understand what I´m writing about, even though I´ve included an .unr file for you to refer to and examine.

Getting started

Now you´ll make the world and place all the needed Actors in it.
1, Create a rectangular room about with the approximate dimensions of 512 x 512 units wide and broad. Don´t worry about being precise when working with this tutorial.
2, Then throw in the crucial Light and a PlayerStart Actors, and make the PlayerStart stand in one of the four corners of the room.
3, Now place three PatrolPoint Actors (found in Actor -> NavigationPoint ->PatrolPoint) in the remaining three empty corners.
4, Finally take a Nali (found in Actor -> Pawn -> ScriptedPawn -> Nali), or whatever other friendly Pawn you can find, and place him in the center of the room.
Now you´ve added all the actors you need, the only thing left to do is to make them work together by changing some stuff in their prefs.

Setting up the Actors:

Now comes the tricky (and fun) part of this process.
1, First open up the prefs of one of the RotationPoints and under the "Events" rollout you´ll find the "Tag" type-in. It will have a default value of "PatrolPoint". Change this value to "Point1" or something similar.
2, While still having the prefs box open, click on each of the two remaining PatrolPoints and change their Tag values to "Point2" and "Point3" respectively. Now you´ve given all the PatrolPoints uniqe tags so they can be set up to link each other and form a loop.
3, Still in one of the PatrolPoints´ preferences box, open the "PatrolPoint" rollout and locate the "Nextpatrol" type-in. It´s value will be set to "None" as default. Change this value to match the _next_ PatrolPoint´s Tag.
4, Repeat step 3 with the other two PatrolPoints, setting their NextPatrol values to exactly match the Tag of the next PatrolPoint. When done correctly, all three PatrolPoints will kind of connect to each other and form a loop. Now you´re finished setting up the PatrolPoints.
5, Now select the Nali Actor and open his preferences. In the "Orders" rollout you´ll find the two type-in boxes "Orders" and "OrderTag". In Orders, replace the default value "None" with "Patroling". Observe the _single_ l in that value. The Nali won´t patrol anything if you don´t type the value exactly like that. Then set the type-in OrderTag value to match the Tag of the PatrolPoint you want your Nali to go to first. >BR? Now you´re all set! Just hit F8 and rebuild the geometry and go play the world! Your Nali should walk around the loop of PatrolPoints you set up. If he does not, compare my PPtut1.unr that I´ve included with the one you´ve created. Also check so that you haven´t made any typos in the linking process. Go ahead and play around with the different prefs of the PatrolPoints, like "pausetime" which sets the time the Pawn shall stop at that Point.


Joining Levels Together

by: Mutant Dandruff
johnnyt@telusplanet.com

If you have ever wondered how the creators of Unreal were able to link the levels of the game in order and you wanted to do so yourself this is the right tutorial for you. I will explain exactly how to link two levels you have created.

First create two levels. If you can"t do this try reading another tutorial first. Make both of them big cubes 512x512x512 is good. Place a player start and a few lights and save. Create another level in a similar fashion. Texture the walls in each level differently, so you don"t mix the two up. Now you are ready to link them. Both the levels MUST be in the same directory.

Open to your "first" level. Now switch to the classes menu, then expand NavigationPoint. Click on Teleporter. Now add the teleporter to the level. A symbol with a little man and an arrow should appear. Now rightclick the teleporter and view its properties. Expand teleporter. The first eight properties affect what velocity you will have upon exiting the teleporter. I always leave the velocity set to 0,0,0 so I don"t even know if they work! Only the last value, URL, is important. Now you might assume that you just type in the filename of the level you want to go to. Oh no, it can"t be that easy. I beileve that this actor may be set up to some day fulfil the server hopping dreams of Unreals designers so you need to enter your URL in in a specific way. This is the format

Filename#Filenameentry?peer

Note that the filename does NOT include .unr
For example is your second level is called Level2.unr your URL would be
Level2#Level2entry?peer

Now open your second level. Also add a teleporter there (right next to the Player Start), but don"t change any of its properties. This is where a teleported player will start. However you still need a player start in case someone tries to play the level on its own or the player restarts the level.

Now reopen your first level again and play it. You may want to put a marker near the teleporter to help you find it. Once you step over the teleporter the familiar blue loading screen will appear and you will begin playing the second level.

Remember: Both levels must be in the same directory, preferably the Maps directory.

You can use this method to create a linear system of levels like Unreal or even create a hub level from which several levels can be acessed.


The MyLevel Package

by: Anthony `Bean` Nichols
bean@planetunreal.com

Importing `MyLevel` Package Objects

This tutorial are for those who are comfortable with UnrealEd. There is a lot of lingo used in here.

The `MyLevel` package is valuable for those who do not want to distribute textures, sounds, music, and other media objects in seperate files along with their maps. When using the `MyLevel` package, textures, sounds, .u packages, etc can be embedding directly into your .unr file so there is no extra files to zip up along with your map when distributing. Many mappers find this to be VERY handy.

-MyLevel Textures and Screenshot

To import textures into the `MyLevel` package, open the texture browser and select File->`Import`.

In the Import Texture dialog, enter in MyLevel for the package. Enter in whatever name or group that you would like. If it is masked, don`t forget to check the masked box. Then, click OK. Don`t save the package. Now, apply the imported texture onto a surface, then do a full rebuild. Now, when you save your map, the texture will stay with your level. Make sure you apply any MyLevel textures to a surface before you rebuild or it will be discarded by UnrealED. When you want to access your `MyLevel` textures, just open the texture browser and use the pull-down list.
When importing a Screenshot for your level, make sure that you enter `ScreenShot` as the texture name and uncheck Generate MipMaps.

-MyLevel Meshes

This is fairly easy. Make sure your mesh is ready and packed into a .u file. Place the .u file into the UnrealTournament\System directory. Then, in the command console of UnrealED type:

obj load file=nameoffile.u package=MyLevel

Substitute the nameoffile with the name of the .u package. Then, add the mesh into the level and do a full rebuild. When you save, it will be embedded.

-MyLevel Sound and Music

For sound:

Open up the Sounds Broswer and click File->Import. Select the sound that you would like to import. When the dialog comes up, enter MyLevel for the package. Then click OK. Use the sound in the map, do a full rebuild, then save.

For music:

Open up the music browser. Go to File->Import. Choose the song you would like to import. When the dialog comes up, enter the name MyLevel and hit OK. Next, goto level properties by pressing F6. Then, got to the list titled `Audio`. Having your song selected in the Music Browser, click `Use` under the song line. Do a full rebuild, then save.

That`s all there is to MyLevel! Pretty simple, huh?

~Anthony `Bean` Nichols

There have been 1745646 pages displayed on this site.


UT Speed Booster

UT Speed Booster / Nali Castle Intro

By: ]V[ATTerminator

Matterminator@planetunreal.com

http://www.planetunreal.com/matterminator/

Tutorial:

Ever had the annoying pauses from when you pick up a weapon for the first time in a game? Well I did, and that was with 128mb RAM. I was told that more RAM would fix it, but it didn't. It does though if you have next to no mods installed, but that's not really an option. For those of you who know your stuff, this is memory swapping I'm talking about. I found a way to reduce it a lot, and make UT generally faster to play. It involves using the Nali Castle fly-by from the original Unreal.

1. Grab the following files from your Unreal CD;

D:\Maps\Unreal.unr

D:\Music\flyby.umx

2. Put them in your \UT\Maps\ and

\UT\Music\ folders respectively.

3. Load Unreal.unr in UnrealED. Don't worry if you can't use UnrealED that well, this is pretty easy to do. Go to 'Level Properties' from the view menu.

4. Click the '+' next to LevelInfo. Next to 'DefaultGameType' type the following, rather than what was there originally;

Class'Botpack.UTIntro'

5. After saving the level, open your \UT\System\UnrealTournament.ini. Find LocalMap=CityIntro.unr and replace CityIntro.unr with Unreal.unr . Save UnrealTournament.ini.

That should make the game run faster. It also loads a bit faster too.

That should make the game run faster. It also loads a bit faster too.

I found this completely by accident, because I wanted the castle fly-by when I started Unreal Tournament. Some levels this works better on that others. Try it and see. It might work on yours too. I've tried having UT-Logo-Map.unr there instead, but that doesn't work as well as this for some reason.


Architecture

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

I won't explain how to build a great architecture, I just can give some tips how to learn it. Because it's just impossible to explain architecture.

People always complain when you rip off other maps, but I have no idea why. That was the way I and many others I know learned some architecture stuff. My first maps were just some cubes stuck together,
then I built a map in the style of dig and dug (the mine maps in Unreal), I looked at Cliffy's architecture in these maps and just built the same. That stuff helps a lot, because you'll understand why he did do it like that...
When you are playing maps, always have an eye on the architecture, try to understand why it looks good (if it does) and try to copy it and maybe improve it a bit.
Once you've "ripped" several styles you'll start developing your own architectural ideas.

If you cannot build something, though you know what it looks like, load the map in the editor and look at the brushes...now everybody should be able to build it (presupposed you know all functions of the editor).
Something that helps as well.....in real-life, when you see an object, try to see it's wireframe, try to build it of the editor primitives in your mind....

Most people start bitching at you when you release your rip-off work, you don't have to release it, but if possible show it to the author of the map that you've ripped and ask what he (are there female mappers btw?) thinks about it, maybe he can provide some hints.

Well.....yeah, I haven't got anything else to say about that. If you have questions ask me...davidm@planetunreal.com


Gameplay Thoughts Part 1

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

Just wanna talk about some of my gameplay thoughts.
Most maps out there are completely without purpose, and
I hate it when level designers don't think about EVERYTHING they add to the map,
you feel it when you play an unplanned map.

Now I'm gonna show some examples for gameplay ideas I like.
It's just about 1on1 or 2on2 , because matches with 16 ppl or so are just spamming and don't need a good layout.

Here a scene from Codex, you know it...

I love stuff like that: Player 1 sees player 2 entering that hallway (first blue arrow)
and knows that he will get out at the 2nd blue arrow. But if player 2 knows that player1 is waiting for him to
kill him on the top, he can return to the lower end of the hallway and try to fool him that way because he expects player 2
to leave the hallway on the upper end.
When you build something like that it's important that player 1 can control all exits, it's not very exciting
if the other end of the hallway is somewhere else in the map...
Here another example, from DM-ArialSE + a topview pic (ph33r my l33t drawing skillz).

Very similar to example 1.

Player 1 can see both exits of the way. He knows player 2 is somewhere in that hallway but not exactly where...
Player 2 knows that player 1 is waiting for him......a cool situation....
Make sure that there is some cool item in that hallway because there must be a reason to go that way....

You can spice it up a bit. Place some health vials or items in that hallway (pic below), so if player 2 is
stupid (sorry @ player2) player 1 can hear player 2 when he is grabbing up the items.
There can also be knee deep water, so player 1 can follow the steps of player 2,
but it may be a bit too easy for player 1.

Next example: Deck16, you all know it......

While reading this look at the pics below.
Player2 is on the lowest level, he wanted to grab the shieldbelt.
Now Player1 knows where he can catch him. The only ways for player 2 to get up again are
- the lift (1), it's pretty easy for player1 to kill him
- the teleporter (2), player 1 can take him down with a rocketlauchner or the shockrifle
-he grabs the jumpboots and jumps up to point (3)

Again the same principle, player 1 knows where player 2 is and from one spot he can see all 3 exits.....
Also important: player 1 is being warned
- He hears the lift sound
- He hears the teleport sound
- He hears the Jumpsound
Imagine that spot without sound, it would not work!!

Ok, in Deck there is a 4th way to get up, you jump on the shieldbelt bar with the jumpboots, and from there onto the ramp above it.....
The map could have been designed better there....

I don't want you to copy these scenes now, just want you to start thinking about stuff like that (if you didn't already).
I'll add some stuff soon.....


Gameplay Thoughts Part 2

by David Münnich

David Münnich

http://www.planetunreal.com/teamvortex/davidm/

On the latest tutorial I was talking about good gameplay, now I want to show how not to do it, I think that's pretty helpful too and makes you think about every single brush and actor that could affect the gameplay or your map.
You must have read Gameplay1 before you read this. The 'Predictability stuff' is important.

1.

Let me start with that one.
You are the red robo babe and the green stick dude is your opponent, he is running away to the question mark (follow the arrows).
Now you don't know if he takes the right of the left way.
In the previous tutorial I said that you just have to be able to control the 3 exits, but in that example the ways are too long, and my rocket too slow, and in the stalwart example you cannot really see all exits, cause your field of view is only 90° to all sides.

To fix that, you need the sound indicators, like lifts, itemsounds, or water....
When he takes the upper way you will hear his steps in the water, the other way he will probably grab up the vials.
It's important that you hear the sounds early enough, if the water/vials come too late, you won't be able to run that way fast enough and catch him..
To make sure that he grabs them you got to do it like in the following pic, in that case you have no choice, he MUST take'em or he doesn't choose a way at all, and just waits for YOU to look for him.

Here the 'MustVial'.
The way must be thin and long enough (you shouldn't be able to pass em with a jump) that you can't pass 'em without grabbing them.

2.

Red = You
Green = Phag1t running away

He can follow the blue arrows.....and you have no clue where he is going to.
He can be anywhere when he's taking route A or B, only way to catch him is C, but if he takes route A you won't have a chance.

Here an idea how to fix it. The green dots are a window (you don't get tru it).
If he enters A you can see it in the window and catch him at B.
You can add the sound indicator stuff if necessary...

And DO NOT think in 2 dimensions, the drawings are not supposed to be a top view!
The A hallway can be a lift that moves upwards and the B point where you try to catch your enemy is on a higher floor.
So please no flat stalwart like maps. Stalwart was made for beginners because a flat map is easier to coordinate.

3. Now something many people ask me all the time

The Room-Corridor-Room syndrome
That's something like that....

That's the way newbies and id level designer (is that the same btw?) build their maps.
Huge rooms interlinked with long thin corridors. It's not hard to tell why that sucks.

As CliffyB once said: Avoid Room, corridor, room "by creating a map that continues to spiral into itself without ever seeming forced or boring.
Try to make your rooms interlock nicely with one another. Remember, a good map is always returning back into itself, like a cloverleaf on a highway or a snake that's eating itself."

Ok, most people will say "What the heck??"
The problem of R-C-R are

-the long thin hallways
-the rooms are just connected on one floor

To avoid it, build some rooms, leave 128 units between them.
Now add big doors instead of hallways and
interlink the rooms on 2 or more floors(!), that makes the big difference (And now you have a snake that's eating itself *cough*).
A good example map is DM-Pah, you find it on my Maps page.

Next problem that happens to people who try to avoid R-C-R is, that the maps are too open, you can look from one side of the map to the other end.....that sucks and should be avoided.
I think I don't have to tell you how to fix it, its really easy, you just have to know that there is a problem. So check your maps, if they are too open and block the view (by placing a crate, a pillar, or just relocating a door....).
You can also see that problem in DM-Pah, it's way too open in some spots, check it out, because "to know how not do it" is a very important part of mapping...

Feedback and suggestions to DavidM@Planetunreal.com


Publishing

Publishing your Level

    By: cyberg][dan
    dan@catapultic.com

    Foreword:

    This tutorial should successfully show you how to publish your finished level in a professional way, with screenshots and all. You won't even have to distribute your texture package.

    Abstract:

    Screenshots and Level Info... two of the most important but most often ignored parts of UnrealEd level creation.

    Assumptions:

    I assume that you have created a level and are completely happy with the geometry, textures, lighting, and overall playability. You should feel ready to put it "out there."

    Introduction:

    I'm sure you notice the level screenshots before you select a level to play when starting a game. It also provides you with the author's name (or alias), recommended number of players, and level title. You've also probably wondered how you can implement that in your finished level. This short tutorial will show you how.

    Steps To Include a Screenshot:

    1. Make a backup copy of the level you're about to wrap up, just in case something happens. Better safe than sorry.

    2. Start up UnrealEd and open your backup copy.

    3. Now take a really good screenshot of your level. This is *always* best to do in spectator mode, so you include more of your level and less of the HUD. Press F11 to bump up the brightness to a desirable degree and hit F9 to capture the screen. The screenshot will now be in your <TournamentDir>\System folder as a raw BMP file.

    4. Now, open up your favorite *quality* image editor. You need something like Photoshop or Paint Shop Pro to handle the color depth conversions without pixellation and quality reduction.

    5. Open your screenshot bitmap file.

    6. Resize the image proportionally (or whatever works best for the image) to 256 by 256 pixels.

    7. Decrease the color depth to 256 colors. Save it and go back into UnrealEd.

    8. Choose Textures from the Browse menu on the side. On the bottom of the screen, click the Import button.

    9. Choose your screenshot file and open it.

    10. You will now get the Import Texture dialog box. Fill in "Screenshot" for the name, "MyLevel" for the package, and uncheck the "Generate Mipmaps" text box. Your dialog should look like the one below:

      Your Import Texture dialog box configuration

    11. Click OK. Your screenshot will appear in a blank package in the Texture window.

    Whew!

    That wasn't so bad now, was it? But wait, we're not done yet. We just have our level screenshot ready to use.

    Setting LevelInfo Properties

    1. Now, navigate to Options menu -> L evel properties... or hit F6 to bring up the Level Properties dialog box.

    2. Expand the LevelInfo node.

    3. You should now fill in the Author, IdealPlayerCount and Title fields. Author can be whatever you desire. IdealPlayerCount should be a single number or a general amount, such as 8-16. Title should be the name of your level--not the filename, but the title (e.g., DM-Peak's title is The Peak Monastery).

    4. Now you need to set the DefaultGameType. Move to this field and press the ellipsis button (...) to move over to the Classes menu on the Browse toolbar. Navigate to *Info -> *GameInfo and within those nodes, find the game type your map is designed for. Click the game type once and move back over to the Level Properties dialog. Click the Use button in the DefaultGameType field to fill the field with your selected game type.

      *Note: All the Unreal game types will be found in UnrealGameInfo and all the UT game types will be found in TournamentGameInfo.

    5. DefaultGameType is taken care of. Now move down to the Screenshot field and click the ellipsis button again. The Browse bar should load up the textures. Select MyLevel from the second drop-down list. Click on your screenshot texture (it should be called Screenshot) and move back to the Level Properties dialog. Click the Use button in the Screenshot field to fill in the information.

    6. That's it! You're done for now. Below is an example shot of the filled-in LevelInfo node:

      Level info

    Publishing To The Web

    Now that you have everything filled in, rebuild your map (as always) and save it. It's generous to zip your .unr map file with a .txt file describing release and copyright notices, as well as contact information.

    Well, that just about wraps it up. I hope you've learned a bunch about zipping your level up cleanly and professionally.

    Have a great time out there, and if you have any questions, feel free to e-mail me.


Adding Screenshots to Your Level

By : Matt Murphy utcity@planetunreal.com

UT City

FOREWORD:

I am suspecting that you have some sort of level ready.

DIRECTIONS:

Start up the Unreal Tournament. Once you've done that go to Player Setup and choose play as spectator. Once you've got that settled start a practice session and choose either 1 or 0 bots. Now start the game and fly around until you find a good spot for a picture. Once there press the F9 key. Now close Unreal Tournament and start up UnrealED. Also start up an image program you have such as Paint Shop Pro, Adobe Photoshop, etc, (NOT MsPaint!). Now, in your image program create a new image that's 256x256 and 72 resolution. Now open up the most recent screenshot you've taken in your UnrealTournament/System directory (Files are named "Shot0001.bmp" for example). Choose the one with the highest number because that's your most recent one. Open that file and copy it to your new file. Now it's going to be larger than 256x256 so either scale it down or resize it in MsPaint. Once you've done that save it as "screenshot.bmp" (or "screenshot.pcx")<--(Without the quotes). Save it in your UnrealTournament/Textures directory. I prefer saving it as a bmp file because it looks better on my computer. Now go to UnrealED and click on the import button on the bottom right side of the screen. Open up your file in the textures directory. Now in the name box put "screenshot" (without the quotes), in the group put "None" (without the quotes), in the package box put "MyLevel" (without the quotes) and uncheck Generate Mipmaps in the Properties section. Then press Ok. Now in the texture viewbar you should see a smaller version of your screenshot. Good. Now press the F6 button to bring up the level properties dialog. Go into LevelInfo, then select your screenshot on the right and then where it says Screenshot as one of the LevelInfo properties, select it. Then press use and it should say something like this: Texture'MyLevel.Screenshot' . If it does then save your map and test it out in the pracitice session dialog in the game to see if it's there.

CONCLUSION:

You should now be able to make a screenshot image for your level.

OTHER:

Questions/Comments email me at utcity@planetunreal.com

-=[ Copyright / Permissions ]=-

This tutorial is copyright (c) 1999 Matt Murphy.
This tutorial is not supported by Legend Entertainment or Epic Games.


Animated Intro Screenshots

by: Eric Poggel
E_Poggel@Hotmail.com

You know those pictures beside the level descriptions in Unreal Tournament?

This will allow you to create an animated (movie) that will show in place of a regular still screenshot.

I assume you already know how to create a regular intro screenshot and import textures, so I"ll skip some of grizzly details. If not, there are other tutorials to help you with that. The first thing you need to do is create the frames you wish to use for your movie.

One method of doing this is as follows..

Enter you level, type in "slomo .1" (no quotes), and hit F9 (screenshot) about 1 (10fps) or 2 (20fps) times a second as you move through the area you wish to be displayed in your movie. Try to be consistent with your timing, for if you don"t, your movie will be quite jerky.

A second method, which is quite easier, but isn"t quite as thrilling to watch is the slideshow method. Take about 5-10 screenshots of your map in various interesting places. When finished, the pictures will change from one to the next at an interval we will set later.

Using a graphics editing program (I use Paint Shop Pro - www.jasc.com) to open your screenshots from the UnrealTournament/System directory. Resize them to a resolution of 256x256 with 256 colors. Save them as pcx files in order using the names Screenshot, Screenshot2, etc.

Open UnrealEd 2 and open your map. On the texture window, go to file / import from .pcx
Open the first image of your animation.
Type "MyLevel" (No Quotes) for package
Type "Screenshot" for Group
Type "Screenshot" for Name
Make sure Generate Mipmaps is unchecked, unless you want a blurry animation when low detail textures are selected in options.

Repeat the above process, but import and type in "Screenshot2", "Sceenshot3", etc. for each sequential frame. Go to the first image (Screenshot) that you imported, right click in the texture window, and go to properties.

Expand the animation tree, and where it displays AnimNext, type in "Texture"MyLevel.Screenshot.Screenshot2"" (No Quotes). You can also click on "Screenshot2" in the texture window and click use. Now right click on "Screenshot2" and go to properties. Set Screenshot3 as the next frame the same way you set "Screenshot2" in "Screenshot". Repeat until you reach the last frame. For this frame, set "Screenshot" (first picture) as the AnimNext.

Close all extra windows and right click on "Screenshot" to go to properties. Set the MaxFramerate to how fast you want your animation to play. 20-25 fps is really smooth, but you"ll need that many pictures for every second that your movie plays. 10 is kinda jumpy, but still produces the desired effect if you are using the movie method. If you want a slideshow of images, set the framerate much lower. Here are some variables and how fast the image will change.

1 = once every second.
0.5 = once every two seconds.
0.25 = once every four seconds.
As you can see, it works on an inverse scale.

After this, click view and go to level properties. Expand LevelInfo. Type Texture"MyLevel.Screenshot.Screenshot" where its says screenshot and enter any other information you wish to be displayed in the appropriate places. Save your level and run to make sure it works.

I have found that about every 15 frames will increase the size of your level by 1mb (about 500kb when zipped). If you don"t want to force 56k"ers (me!) to wait through a long download, I would recommend using the slideshow method or keeping the movie length to only a few seconds.

For an example of this tutorial in action, download CTF-Antimatter][ at NaliCity.


Animated Sequences

by: Machismo a.ka. The Indian Fakir
cool_machismo@yahoo.com

GIVE ME MORE INFORMATION DAMNIT!

Let me be frank. Since there are going to be so less people who want to do animated movie like opening sequences this is going to be a fast and bitter tutorial (don"t mind me I don"t know what the hell I"m talking about half the time :) - but don"t worry this tutorial will get you to where you want to go) . Since you are reading this tutorial lets hope you are interested in doing that. Ok I hope everyone who"s reading this tutorial has played both Unreal and UT and not just one of them - I don"t know why I go around making stuuuupid comments like that but it had to be made. Ok this tutorial will set out how to make those animated sequences that you see when you start Unreal and UT; the end Unreal sequence and the trophy sequences in UT. Another harsh reality - no one is going to want to see your animated map except your friends whom you can force to watch your map with dire threats (a very nice way of showing off your skills and boasting lol). Its also a nice way of showing off any good map that you have made. What am I blabbering about, lets get with it.

THE SECRET (BUT NOT ANYMORE):

When I first took up Unreal editing I was really impressed by the opening and end sequences knowing the editor and all that kept me wondering how the hell did they do that. Well as the heading of this tutorial suggests the whole thing is controlled by the interpolation point (hereafter referred to as Interpol, located under the actor class keypoint). I"ll assume that you have a map that you want to animate. If not then build four boxes connected to each other to form a large square - got that?. Lets dive into this cool pool pal, here"s how to go about it:

1. At the beginning of your level where ever you want the animation to start place a player start high up in the air so that if you were to play the level you would fall from a height. You need to do this or its going to be a little awkward, this will make the beginning more smooth. You"ll understand why later.

2. A little below the player start place a trigger. Under its properties|collision give it a nice big collision radius and height so that the trigger will get triggered no matter what. Also give it an event name.

3. Add in a special event from under triggers anywhere in the level. Under its properties set the following:
(a). Its tag must be the same as the trigger you placed above. Give it a event name we will be needing it in a while.
(b). Under object|initial state set it to player path. This lets the game know that it has to move the player around the paths we specify and that the player has no say in the movement.

4. Now for the main part. Since the whole map is run by the Interpol we need to set them up properly. The Interpol decides how the camera (think of it as a moving handcam) moves about, where it does turns, how fast it moves at each point, etc. Locate them under keypoint and place them around your level. The placement is really up to you but a few tips - you can place as many points or as less as you desire, I almost always use the top down view to check out the rotation to see that the red arrow is pointed in the direction that I want it to take. At this point some of you make be wondering about how to make turns - don"t worry about it too much. Say you have point a, b and c is around the corner - have a point at b and give b a small twist in the top down view to the left. That should take care of itself. Be careful about those turns though I"ve found myself doing unexpected turns on the corners. So do the placement carefully (and yes I lied before when I said not to worry :). Do some experimentation with the placement - this is not something that I can hold your hand over. Ok now that the points are all set over the level do the following to its properties:

(a). Do a select all interpolation points and set all their tags to the event of the special event. Why? So that when you enter the level the trigger sets off the special event which tells the whole level to make the player take the path laid down by you. You should see the trigger connected to the special event and all the interpolation points connected to that one special event by a spider of red lines.

(b). Ok move to the very first Interpol that you placed. Under its properties expand interpolation point - we are bothered with only four of them:
-bEndOfPath - false for all except for the last point where you want the movie to end. One interesting point of note here is that you can achieve smooth endings by using the following technique. Say you have a line of paths approaching the end of your level and there you have a statue right smack in the middle. From the line of paths build a circle of paths by placing say hypothetically 10 points around the statue and don"t set bEndOfPath for any of the points in the level. What you will have is a line of Interpol"s coming to the statue and a circle of them around the statue. You should also adjust the points so that a few are pointing in at the statue and the rest of the points form a kind of circle to help you circle the statue. The cam will keep moving around the statue give you a "press esc to begin" message and start at the beginning of the level.

- bSkipNextPath - Depends on the situation. You are going to use this only once in a while. Say you have point a, b, c and d. a leads to b; b has SkipNextPath to true and c has bSkipNextPath to false. As should be obvious by now we need point c to tell the game not to skip the next point or there would be no end to the skip path. You can use this technique to increase speed gradually (see below).

- RateModifier -The rate at which the the camera moves needs a little experimentation......again. .5 is a nice slow speed that allows you to get a good look at the surroundings. Play around with it you can achieve some cool effects by slowly increasing the speed from point to point until you are virtually zipping along - say behind a car on a high way -we"ll deal with that next.

- Position - Just what the name suggests, what is the position of that point. Set the first point to 0, second to 1 and from the second if you have a set of points in the same line in the front the position of 3 to that point where you want to move to next in the game.

That"s all with the Interpol"s this should be enough to do any path you want to take on your level.

5. Ok say you have a highway type level and want to see some cars moving around these is how you need to do it:
(i). Set up the Interpol"s along the highway lets say for this example in a straight line. We have points 10, 11 ,12, 13, etc. running along the highway. At point 11 say 1/4th the way along the highway set up a trigger give it an event name and a nice big collision radius and height so that you don"t miss it.
(ii). Behind point 10 in a garage kind of thing place any one of the cars from under decoration. Set its tag to something.
(iii). The main part of this section is here. Expand Brush|Mover from under classes and make sure that attach mover is selected - finally getting to use that one!. Read the explanation given by Epic in the script box in green. The texture is not important make a small brush that fits under the car and cannot be seen from above or the sides and hit the add mover button.
(iv). Under the attach movers properties set - AttachMover|AttachTag to that of your cars tag; under events|tag give the mover the same tag as the trigger that you placed before; object|initialstate to triggeropenedtimed. Also you need to set the following under mover :- MoverEncroachType - Return; MoverGlideType - MoveByTime; MoveTime - Depends set it to say 3 for a fast car; NumKeys (not KeyNums) - How many moves or keyframes the mover will be able to perform (since this is not a mover tutorial all I can say is that if you just want your car to move in a straight line then forget it, but if you want it to do all sorts of twits and turns the amount of twists and turns that you want it to do should equal the NumKeys; StayOpenTime - I always give quite a large number as we don"t want to see the car moving backwards all the way or something.
(v). Ok hit mover keyframe > key 1 and move the car where you want it to go. If for example you had set the NumKeys to 5, hit key 1and after that hit key2 the mover will move back to key0 that is normal. From there move it to the second position and then key3 and so on. At the end hit key0 to set the mover back to the original position. Key 1 can be a straight move, then when the mover is at key 2 you can give it a little turn and another turn at 3 and do a complete circle so that it reaches then end position where you want it to go.
(vi). Go to Interpol 9 set its rate modifier to a slow amount and move to 10 increase the amount, keep doing this (increase the rate that is) till you reach the end of the highway and turn off into another section. The effect that I"m trying to convey is that you come out onto the highway at a slow rate and suddenly under you the car should come along moving at a fast pace and then since the Interpol rates increase you increase your speed along with it then turn off the highway into another section.

6. Hit F6 to open the level properties enter your name and all that, under DefaultGameType hit use after expanding info|gameinfo|tournament game info and selecting UTIntro. After a rebuild when you enter (this may be obvious but don"t save the map with any extension like dm,etc.) you should feel like its just like the opening UT sequence.

SOME GENERAL NOTES:

One cool effect that is a virtual corollary to the above is the ending unreal sequence. There the nice effect of being inside and outside the escape pod is achieved. How this was done was to just circle the pod while in the beginning stages of takeoff using Interpol"s and then using Interpol"s the rest of the way to give a feeling of being inside the pod. I mentioned how to use the trigger to set off the cars, another cool effect is to come at a door at a fast rate slow down and hit the trigger to the door, the moment the door opens take off again. I"m totally deviating from the topic so I"d better stop. This tutorial has hopefully answered your questions (if you had any in the first place :). If not please email me at my add and I"ll try to update you and the tutorial simultaneously. Since I wrote the tutorial in the night instead of sleeping I hope its lucid. That"s the end of this sequence.


Places to Submit Maps

Places Where You Can Submit Your Map(s)

By: Matt Murphy

Name | Type of Maps Allowed
UT BOOTY UnrealCore Nali City Frag Facility MappeD Real Maps W-A-M Urban Distortion | All All All All Assault and CTF Maps Only All Assault Maps Only All

Know a site that's not listed here? Email Me


 Advanced Death Messages for Weapons

By Dragonfly Matthew

Intermediate

Introduction:

UT normally makes an assumption that any kill was caused by the weapon the killer was holding at the time. This is usually ok because most weapons kill instantly, or fast enough that you don’t have time to change weapon.

However, particular weapon like the Eightball sometimes take a long time to kill someone and you may have changed weapons by then. In this situation you have to do something special.

The default UT weapons fix this problem with damagetypes. For example, redeemer kills have the damagetype “redeemerdeath” and whenever someone dies from “redeemerdeath” they get a redeemer death message. Great. The only problem is that this is all coded in the gametype function so unless your weapon comes with a special gametype, you cannot change death messages this way. We need a different approach.

When someone is killed with “specialdamage”, the death message used is the level’s current specialdamagestring. When you are killed in a pressurezone, the Specialdamagestring is changed to something appropriate and you are killed with specialdamage. We will copy this for our weapon.

The actual stuff

At the top of your projectile (or whatever it is) add these properties. If the projectile is one that cannot hurt its owner (like a plasma sphere) you only need the first of there. If the projectile can hurt its owner (like a piece of flack) then you need all three.

var string DamageString; //The normal kill string

var string DamageStringselfhe; //The suicide kill message (male)
var string DamageStringselfshe; // Ditto for females.

In your weapon’s defaultproperties, give these strings values. The text %o will be replaced with the victim’s name, and %k with the killers. A very boring example would be:

Damagestring="%o was killed by %k with a grenade."
Damagestringselfhe="%o killed his own dumb self."
Damagestringselfshe="%o killed her own dumb self."

Ok. Now choose one of these two sections..

If your projectile uses the Takedamage function to cause damage:

This one is simple. Somewhere in your projectile code (for projectile weapons) there will be a line a bit like this:

Other.TakeDamage(Damage, instigator, HitLocation, -10000.0 * Y, MyDamageType);

First we must set up the death message. If the weapon cannot hurt its owner, you only need this line:

Level.Game.Specialdamagestring=damagestring;

Before the TakeDamage function. Then change the damagetype to “specialdamage” and you’re done!

If your projectile can end up hitting its owner, instead of the single line above you will need something like this:

if (Other==Instigator)
{
if (Instigator.bIsFemale) Level.Game.Specialdamagestring=damagestringselfshe;
else Level.Game.Specialdamagestring=damagestringselfhe;
}
else Level.Game.Specialdamagestring=damagestring;

Where Other is the thing you are hurting. This selects the correct death message, and stops you getting messages like “Dragonflymatthew killed Dragonflymatthew with a rocket!”.

As above, change the damage type to special damage.

Done!

If your projectile uses the HurtRadius function to cause damage:projectile uses the HurtRadius function to cause damage:

I am assuming that all weapons with a hurtradius can hurt their owner, if not then just set the SpecialDamageString and call the hurtradius function with “specialdamage” as the damage type. Otherwise, it gets more complicated.

We have to change the hurtradius function. Actually, hurtradius is a “final function” so instead we copy it into another function.

Where your weapon used to call the hurtradius function, change it to spechurtradius.

Now, you have to alter your hurtradius so that before it hurts each pawn, it checks to see whether they are the instagator and if so change the death message. All you really need to do is paste this function into your code.

function specHurtRadius( float DamageAmount, float DamageRadius, name DamageName, float Momentum, vector HitLocation )
{
local actor Victims;
local float damageScale, dist;
local vector dir;
local bool bAlreadyDead;
local Pawn PVictim;

if( bHurtEntry )
return;

bHurtEntry = true;
foreach VisibleCollidingActors( class 'Actor', Victims, DamageRadius, HitLocation )
{
if( Victims != self )
{
dir = Victims.Location - HitLocation;
dist = FMax(1,VSize(dir));
dir = dir/dist;
PVictim=Pawn(Victims);

if (PVictim==None)
continue;

damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);

if ((Victims.Isa('PlayerPawn') || Victims.Isa('Bot')) && (Pawn(Victims).Health < 0))
bAlreadyDead=True;

//OK, lets check if this guy we’re about to hurt is the instigator, if so then we change the death
message.
if (Pawn(Victims) != Instigator)
Level.Game.SpecialDamageString = DamageString;
else
if (Pawn(Victims).bIsFemale)
Level.Game.SpecialDamageString = FemaleSelfDamageString;
else
Level.Game.SpecialDamageString = SelfDamageString;

//Then we go and hurt them, as normal.
Victims.TakeDamage
(
damageScale * DamageAmount,
instigator,
Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,
(damageScale * Momentum * dir),
DamageName
);
if (!bAlreadyDead && (PVictim.Isa('PlayerPawn') || PVictim.Isa('Bot'))
&& (PVictim.Health < 0) && (PVictim != instigator) )
{
BroadcastLocalizedMessage(class’DeathMessagePlus’, 0, Instigator.PlayerReplicationInfo, PVictim.PlayerReplicationInfo, None);
}

}
}
bHurtEntry = false;
}

That’s it. Now you should get the right death message no matter what weapon you are using when your victim dies.

Problems:

The death messages will appear white, which is not the normal death message colour.


An Idiots Guide to the Console

by Postal, who is NOT an idiot

A pre-beginner (that or "You’re-An-Idiot") tutorial

Ok, I have found out there are some fools out there that do not know how to use the UT console. Now, I would say I used to know how you people feel, but that is not true since I was born knowing how to use the console. So I am making this tutorial for you guys who have no idea what to do.

Ok, this is STEP 1. The important step. Pay attention. Do not skip this step! You access the console by either hitting Tab or hitting ~ or ` (AKA console).

Now when you have the console open there are a bunch of cool things you can do if you first type:

Iamtheone (This will activate cheats if they are not already enabled.)

Do not type IAMTHETHREE OR IAMTHETWO or WEARETHEONE, for UT will not recognize these things and will secretly mock you from within the pawn AI code until the end of time. And I think IAMTHATIAM is taken elsewhere. Sorry.

Then you can use things like:

God makes you invulnerable, type it in again to turn it off. Typing SATAN doesn’t work in this UT patch; neither does BILLGATES.

Allammo gives you 999 ammo for every weapon you have. WHAT DID YOU THINK IT WOULD DO?!

Invisible makes you invisible, type it in again to turn it off. Just like God mode. Of course, as you continue to read the fine print you will discover that I lied. ‘Invisible 1’ makes you invisible. Invisible 0 undoes this.

Fly lets you fly, type in ‘walk’ to end it. Try this from great heights without god mode. Come on, it’ll be fun…

Ghost lets you phase through walls, type in ‘walk’ to end it. Do we sense a pattern here, folks? Also try using walk between walls, great fun.

Walk set you to default walking. And I thought it would let me skip rope. Darn.

Addbots (number) add the number of bots to the game i.e.: Addbots 5 adds 5 bots. You may not type:

Addbots (–5*e^pi*I) for some reason. UT hates complicated math.

Behindview 1 set you to 3rd person view

Behindview 0 sets you to normal view

Killall (class) removes all of the named class i.e.: Killall weapon. Try ‘Killall Pawn’

Playersonly pauses game, type it in again to turn it off. Good for screen shots or dodging pulsegun volleys.

Slomo (number) sets the game speed, 1 is normal, 2 is double speed, .5 is half speed.

Fov (number) sets you zoom, 90 is default 30 is a good zoom in. FOV above 90 is fun too.

Now the good stuff:

Summon (packagename).(itemname)

This is the real tool, summon botpack.shockrifle would place the shock rifle in front of you. You can use with anything, for example: summon war.jetpack, or summon u4et.m16 or any such weapon, item, decoration, effect, etc. If the item is part of botpack, you can omit the botpack and just type things like ‘summon shockrifle’

Set (itemname) (variable name) (value)

With this you can have lots of fun

Try set enforcer hitdamage 50000 to make the enforcer insta-kill

Or set pulsegun projectiletype warshell for a little more powerful weapon

Now let me show you some useful stuff

Setinput x Fov 30 | OnRelease Fov 90

This would make it so when you hold down x it zooms in with any weapon, and when you let go, it zooms back out. This is a primitive alias.

Setinput z Behindview 1 | OnRelease Behindview 0

Set you in 3rd person view when you hold it

Thanks to:

PlanetUnreal's console list

Someone else asking my what summon was for.

And to my trusty pet grammar slave Nephilpal who couldn’t resist the urge to edit and add his own special patented brand of disturbed humor to this document.


Burning Enemies

By Postal

Intermediate

Several times I have been asked how to make a weapon set someone on fire. So instead of continuing to shrug off these people, I have decided to make a tutorial. This code was given to me by Necron_99 and its quite simple so this is what I’m sharing with you, I doubt that Necron would mind.

First of all, we will make a projectile that will stick to the person and hurt them.

//===============================================
// BurnerProj.
//===============================================

class BurnerProj expands Projectile;

var float HurtTime;
var float LifeTime; //how long it lives

Function Tick(float
            deltatime)
{
HurtTime+=deltatime;
LifeTime-=deltatime;

            if (HurtTime>0.3)
{
//Hurt the target
Base.TakeDamage(Damage,Instigator,Location,Vect(0,0,0),'Burned');
            HurtTime=0;
// Basically ever .3 deltatime this hurts some
            one
}

            if ((LifeTime<0)||(Base==None))
{
Destroy(); //When
            its life is up, it dies
}
}

defaultproperties
{
 Damage=5.000000 // How much damage it does
 Mesh=LodMesh'UnrealShare.FlameM' // What it looks like
bUnlit=True
}

If for instance you were making a poison gas grenade, or poison arrow, you could always change the damage type and remove not use that mesh.

Now we need this projectile to be attached to the person.

So in the projectile add:

simulated function ProcessTouch (Actor Other, Vector HitLocation)
{
local BurnerProj AnOther,FinalBurn;

if ( Other.Isa('Pawn')) // If the targets a pawn(bot, player, monster, etc.)
{
//This makes sure a person is only set on fire once

foreach AllActors(class'BurnerProj',AnOther)
{
If (AnOther.Base==Other)
FinalBurn=AnOther;
}

//If that person not already on fire

If (FinalBurn==None)
{
//Make the fire
FinalBurn=Spawn(class'BurnerProj',Instigator,,Other.Location,Other.Rotation)

 //Set if to have a life time of 1(good for flame-thrower, but if you
//are making a incendiary arrow, or so forth, crank it up to something like 5

FinalBurn.LifeTime=1.0;

// Attaches the fire to the target

FinalBurn.SetBase(Other);
 }
 else
 {
 // If the target already on fire, make the fire last longer.
 FinalBurn.LifeTime+=5.0;
 }

}
}

Hope this helps your pyromaniac urges.


EXEC Tutorial

by Postal.

Beginner

Before Mutators, some of us old skoolers used EXEC’s in Unreal. An EXEC is a series of console command (Read the console tutorial, if you don’t know what I am talking about) saved in a .txt file that can be loaded in game.

It’s all very simple, you make a .txt file in your UT/System dir. And you place a list of console command in there. So for instance you wanted to make a cheat EXEC. Make a txt file called, lets say, cheat.txt. Then open up that file and place in it:

Iamtheone
god
loaded
allammo

Now save this file. Then in game you hit ~ and typed "exec cheat.txt".

It will activate cheats, place you in god mode, give you all the weapons except for the redeemer, and then give you 999 ammo for you weapons.

Hopefully that gave you the right idea, now try this.

Bizarro had put this together a while ago it simulates space fighting in UT, its not perfect and has a bugs, but it can be fun.

Summon botpack.fighter
set pawn mesh fighterm
set fighter drawtype DT_None
set zoneinfo bWaterZone true
set Pawn UnderWaterTime 9999999.0
set Pawn WaterSpeed 340.0
set Pawn DrawScale 0.5
set Pawn CollisionHeight 20.0
set Pawn Physics PHYS_Swimming

Bots sometimes don't navigate too well as space fighters, but the player control is fine.

As well the teamcolor overlays apply to the ships in a cool symmetrical pattern with no tweaking!

Be careful, on big maps, some people will fly far out into the sky and snipe at everyone.

The bug with this exec is that more often than not, you won't be able to move vertically until you respawn.

Hopefully now you have an idea of the types of things you can do with EXEC’s.

Have fun.


Homing Missiles

by Postal

Intermediate

I am quite sure we all like having a lock on someone with the eightball, it is always fun to know you are going to hit someone with a little package of pain. But perhaps you are sick of having to keep aiming at the stupid bots as they run around like headless chickens. Well now I shall tell you what to do about it. We are going to make a subclass or RocketMK2. We are going to modify the code used in the seeking missiles to find a target them by themselves. So to go over quick idea, the eightball finds the target you are looking at, and tell the rocket that, we are going to make the rocket find its own target.

So lets look at the seeking rocket code:

simulated function Timer()

This is timer so it is called upon constantly to keep updating the course of the missile towards the target

{

local ut_SpriteSmokePuff b;

local vector SeekingDir;

local float MagnitudeVel;

if ( InitialDir == vect(0,0,0) ) InitialDir = Normal(Velocity);

if ( (Seeking != None) && (Seeking != Instigator) )

{

If the guy we are aiming at is not you or if that guys doesn’t exist

SeekingDir = Normal(Seeking.Location - Location);

if ( (SeekingDir Dot InitialDir) > 0 )

{

This code makes it home in on its target

MagnitudeVel = VSize(Velocity);

SeekingDir = Normal(SeekingDir * 0.5 * MagnitudeVel + Velocity);

Velocity = MagnitudeVel * SeekingDir;

Acceleration = 25 * SeekingDir;

SetRotation(rotator(Velocity));

}

}

And this makes the smoke behind the missile.

if ( bHitWater || (Level.NetMode == NM_DedicatedServer) ) Return;

if ( (Level.bHighDetailMode && !Level.bDropDetail) || (FRand() < 0.5) )

{

b = Spawn(class'ut_SpriteSmokePuff');

B.DrawScale = 0.5;

b.RemoteRole = ROLE_None;

}

}

So what we need to do is have the rocket find its own target.

foreach visiblecollidingactors(class'Pawn', I, 2000,, true)

That will find all pawns in the visible area for 2000 unreal units and refers to them as I for reference.

So I ended up with this:

simulated function Timer()

{

local ut_SpriteSmokePuff b;

local vector SeekingDir;

local float MagnitudeVel;

Local Pawn i;

Reference term for the pawns we find.

if ( InitialDir == vect(0,0,0) ) InitialDir = Normal(Velocity);

If ( (Seeking == None) || (Seeking == Instigator) )

{

If we havent got a target or if that target is you.

foreach visiblecollidingactors(class'Pawn', I, 2000,, true)

{

If (i != Instigator && I.Health >0)

{

If the target is not dead or you.

Seeking = I;

New target.

}

}

}

Else if ( (Seeking != None) && (Seeking != Instigator) )

{

SeekingDir = Normal(Seeking.Location - Location);

if ( (SeekingDir Dot InitialDir) > 0 )

{

MagnitudeVel = VSize(Velocity);

SeekingDir = Normal(SeekingDir * 0.5 * MagnitudeVel + Velocity);

Velocity = MagnitudeVel * SeekingDir;

Acceleration = 25 * SeekingDir;

SetRotation(rotator(Velocity));

}

}

if ( bHitWater || (Level.NetMode == NM_DedicatedServer) ) Return;

if ( (Level.bHighDetailMode && !Level.bDropDetail) || (FRand() < 0.5) )

{

b = Spawn(class'ut_SpriteSmokePuff');

B.DrawScale = 0.5;

b.RemoteRole = ROLE_None;

}

}

And that all we need for a self guided missle


Make a Shotgun

by Postal

//
This is designed to be a simple method to make a shotgun, instead of reading through the whole of Windex's irc log 3, but I do suggest that you read through the whole log, it includes many things not in this short tutorial. The log can be found at www.PlanetUnreal.com/WoD
//

Tutorial based on an irc chat lesson by Windex. Also thanks to the myriads of people in that chat, who talked so much that I could not edit it all out, and had to rewrite the whole thing.
//

You ready to make a weapon of destruction?

We are going to make a shotgun capable of loading up multiple shells with alt fire, sort of like how you can load up multiple rockets in the eightball, but not quite.

We could make a shotgun that shoots grenades in alt, or nuclear missiles, or black holes, or what ever you can want, but not today.

Now this shot gun we are going to make in primary fires one shell just like a normal shot gun, but with alt fire you can load up more shells to fire in primary. So you hit alt fire once you now will shoot *two* shells at once instead of just one. This will have a maximum of 4.

//Note: About 30 pages of how a real shotgun works in comparison to this game one was edited out here, please send thanks in cash to Postal. :)

Ok Open up unrealed, henceforth refereed to as ued, you should have at least UT version 436, but this should work with all UT versions, and if not for a few of my changes, all the unreal versions. We will be use ued 2.0, which will deprive us of the old joys of ued 1.0 crashing and losing lots of work.

Open the actor browser (view-actor class browser) open up inventory, then weapon. Double click on flakcannon to open it, minimize the window that opens up. Then double clicks on automag, and minimizes that same window that popped back up.

Now click on the weapon class to highlight it the right click, click new. Package is what the *.u file will be named, and name is what the thing you are making is named. Type in MyMod for Package, and Shotgun for name and hit ok. Maximize the window that pops up now. This is where you will edit code.

On the left you will see a list of the classes you have open, there will be automag, flakcannon, and shotgun, you can switch between them by double clicking on those, now double click on flakcannon. Find function fire can copy the whole thing in to you shotgun. Do the same with function AltFire, and state normal fire, and function PlayPostSelect. Now you can close the flak cannon class by double clicking on it and hitting the little icon all the way on the left of that bar on top. Now copy the ProcessTraceHit function out of the automag into you shotgun and
the automag.

//Warning Boring Part

You probably wonder what all that stuff is, even if you don't here what it does, function fire and alt fire tell the computer what to do ever time you pull the trigger *ahem* click the mouse, the state of normal fire is used by function fire for other parts of the firing process, there is a state altfiring, but we are not using that. function PlayPostSelect is what the gun does when you select it in the game, its that animation of it coming up and sounds and so on.

Now for ProcessTraceHit, this has the computer make a line coming from where it was specified to start and until it hits something, well actually that's trace, but this is what effects are made where the trace hits, and so on.

//End boring part (be happy that was not about 10 pages long like in original)

Back to code, delete everything in the state normal fire except the begin so it looks like:

state NormalFire

{

Begin:

}

Why? Because we don't need any of that. Now look in the function fire, you will see an if statement saying "if (AmmoType.UseAmmo(1))" an { and a lot of stuff then another } cut everything inside that except for the GoToState('NormalFire'); and move it behind the begin in the start NormalFire. All right now place before the begin in the state normal fire "ignoresFire, AltFire;" (minus the quotes) this keeps things from being messed up by function fire and alt fire (tsk, tsk, tsk, no reloading when shooting).

//Note if you copy and paste you may need to refresh the actor class browser by double click on the name of the class in that left column. OK we can clean up function fire to be only:

function Fire( float Value )

{

if (AmmoType.UseAmmo(1))

{

GoToState('NormalFire');

}

}

Since we are going to have more then one-shotgun shell, we are going to need to keep track of them, so we make it a variable. add var int LoadCount; after the "class shotgun expands Weapon;"

Now we don't need anything in the function alt fire that's currently there, so we are going to remove it all, make you alt fire look like this:

function AltFire( float Value )

{

if (AmmoType.UseAmmo(1))

{

}

}

Now... Within that if/then we want to put code to increment the LoadCount var every time someone presses alt-fire but only up to 4, after 4, we want the gun to fire instead of loading more.

So... in the ammotype if/then... we put this code:

if (LoadCount < 4)

{

LoadCount++;

}

But we don't want to load up to many shells so it end up like:

function AltFire( float Value )

{

if (AmmoType.UseAmmo(1))

{

if (LoadCount<=3)

{

LoadCount++;

GoToState('reload');

}

else

GoToState('NormalFire');

}

}

you are probable wondering where the GoToState('Reload") came from, we what the gun to look like it adding a shell, so that make its look like its reloading. Thing is we need to make a state reload. So... make a new state called "Reload" like this:

state Reload

{

Begin:

}

First make it ignore fire and AltFire... Because we don't want to be able to fire while the gun is cocking. :) Then... add this block of code after the begin:

FinishAnim();

PlayAnim( 'Reload', 1.2, 0.05);

Owner.PlaySound(CockingSound,

SLOT_None,0.6*Pawn(Owner).SoundDampening);

FinishAnim();

PlayAnim( 'Fire', 1.2, 0.05);

FinishAnim();

Finish();

So it becomes:

state Reload

{

ignores Fire, AltFire;

Begin:

FinishAnim();

PlayAnim( 'Reload', 1.2, 0.05);

Owner.PlaySound(CockingSound,

SLOT_None,0.6*Pawn(Owner).SoundDampening);

FinishAnim();

PlayAnim( 'Fire', 1.2, 0.05);

FinishAnim();

Finish();

}

Now you are probable wondering what some of that means, well. . .

FinishAnim() pauses execution until after the current animation is finished playing... So you don't start playing one animation in the middle of another.

PlayAnim()... Well... Plays an animation... The first parameter is the name of the animation.. Second and third have to do with speed and framerates... I usually
just leave them alone... :)

PlaySound... Well... Plays a sound the SLOT has to do with where the sound is being played from...

SLOT_None is fine for our purposes :)

0.6*Pawn(Owner) is volume control and we play FireAnim during reload because of a glitch in the mesh... The reload animation ends on an odd frame... It leaves the gun
sticking at an odd angle so the fire animation is played to leave the gun in the right position.

Now let's modify the PlayPostSelect function , since we are using a different
mesh we need different code, place this in replacement:

PlayAnim('Reload', 1.3, 0.05);
GoToState('ResetPos');

So... Now we have to make a ResetPos state...
which should look like this:

state ResetPos

{

Begin:

FinishAnim();

PlayAnim('Fire', 0.9, 0.05);

Finish();

}

So when is PlayPostSelect called?

PlayPostSelect() is called just after the weapon is brought up automatically. So that happens after every time the weapon is brought up... So it is only going to run ResetPos once every time you switch to it.

Now go to the state normal fire and delete everything between owner.makenoise
and PlayAnim

AdjustedAim = pawn(owner).AdjustAim(AltProjectileSpeed, Start, AimError,

True, bWarnTarget);

GetAxes(AdjustedAim,X,Y,Z);

Spawn(class'WeaponLight',,'',Start+X*20,rot(0,0,0));

Start = Start + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z *

Z;

Spawn( class 'MasterChunk',, '', Start, AdjustedAim);

Spawn( class 'Chunk2',, '', Start - Z, AdjustedAim);

Spawn( class 'Chunk3',, '', Start + 2 * Y + Z, AdjustedAim);

Spawn( class 'Chunk4',, '', Start - Y, AdjustedAim);

Spawn( class 'Chunk1',, '', Start + 2 * Y - Z, AdjustedAim);

Spawn( class 'Chunk2',, '', Start, AdjustedAim);

Spawn( class 'Chunk3',, '', Start + Y - Z, AdjustedAim);

Spawn( class 'Chunk4',, '', Start + 2 * Y + Z, AdjustedAim);

Gone so you have left:

state NormalFire

{

ignores Fire, AltFire;

Begin:

CheckVisibility();

bPointing=True;

Start = Owner.Location + CalcDrawOffset();

if ( PlayerPawn(Owner) != None )

{

PlayerPawn(Owner).ClientInstantFlash( -0.4, vect(650, 450, 190));

PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);

}

Owner.MakeNoise(2.0 * Pawn(Owner).SoundDampening);

PlayAnim( 'Fire', 0.9, 0.05);

Owner.PlaySound(FireSound, SLOT_None,Pawn(Owner).SoundDampening*4.0);

}

We are now going to make the code that makes the gunfire.

We are going to use to loops so go place these variables in under where we place them first:

Var Int Loads;

Var Int Shots;

Now add this to the fire code:

for(loads=0;loads {

for(shots=0;shots<10;shots++)

{

TraceFire(1.7);

}

}

This shoots 10 shots for each shell loaded the TraceFire(1.7); tell the gun to shoot a round randomly with in its designated radius of 1.7, a larger number would be less accurate and 0 would be right on the dot now add this at the end the state before the last }

LoadCount=1;

GoToState('reload');

Finish();

That preps the gun for the next round. Now for the last few parts. got to ProcessTraceHit. replace WallHitEffect with UT_LightWallHitEffect so it leaves bullet holds decals. and replace hitdamage with 5 so it does 5 damage per pellet.

Now go to normal fire and remove the line:

Start = Owner.Location + CalcDrawOffset();

Now compile it, hit the icon second to the left on that top bar of the window, there should be no errors.

Now minimize that window and go back to the actor classes window, right click on shotgun and click default properties.

Expand weapon and in ammo name type in flakammo, it should then change to Class'Botpack.FlakAmmo' close weapon and go to display and go to mesh and change that to LodMesh'UnrealI.QuadShotHeld' and close display. Open up inventory and place in pick up view mesh LodMesh'UnrealI.QuadShotHeld' place in third person mesh and player view mesh LodMesh'UnrealI.QuadShotHeld' now expand playerview offest and change x to 20, y to -10 and z to -20 change player view scale and thirdpersonscale to .7 Also look for the pickupammocount and change that to 20

Now exit out of the shotgun default properties, and in the actor class browser go down to the bottom and click the box MyMod, go to file and hit save selected packages, that saves your work, now exit out and get into UT, in game activate cheats and type in summon mymod.shotgun

Have fun!

Note: there are still many bugs and little details like no firing sound, but you now have a working weapon you can perfect.


Model Importing

by Windex

windex@planetunreal.com

I n t r o d u c t i o n

If you've been writing UnrealScript for any length of time, you've probably started to find yourself wishing you could include new models in your mods. There are, after all, only so many ways Unreal's existing models can be used. I'm not going to explain here how to make your own models, since that's an entirely different art form in itself. If you already know how to make your own models, though, or know someone who does, then the next step is to figure out how to import these models into your UnrealScript package. That's what this tutorial is for.

3 d s 2 u n r

Those nice people at Legend Entertainment, in their infinite wisdom and glory, have written a nice little program that converts .3ds files into Unreal format. This program is called 3ds2unr, and can be downloaded for free here.

This program, along with your files in .3ds format, is all you'll need to get a snazzy new model imported into your UnrealScript package. Before going on, though, it would probably help to be familiar with the things I explain in the Using Unreal -make tutorial.

T h e P r o c e s s

Once you've got 3ds2unr, the importing process is not too difficult, although it can be a little difficult to figure out just by reading the documentation that comes with the program. Thus the need for this tutorial. Anyway, just follow these few simple steps, and you should be fine.

1: D i r e c t o r y S e t up

The first step is to get a special directory set up that will be used for importing your models. Exactly how you should do this is not set in stone, but this is the way I do it, and it's always worked for me. Anyway, make a new directory off of your Unreal directory called "Models". Within this directory, make three sub-directories: "3ds", "Models", and "Classes".

Within the "3ds" sub-directory, place your 3ds2unr.exe file, as well as your .3ds files. Note that there must be one .3ds file for each animation in your model. I won't go into too much detail about exactly how the .3ds files have to be prepared, since that falls more in the realm of modeling than coding.

2: R u n 3 d s 2 u n r

Once you've got your directory set up, you need to run 3ds2unr. Go to Start > Run, and execute 3ds2unr.exe with a few parameters after it. The first parameter should be the name of the model. This is the name that the model will be known as in Unreal, and the name you'll reference it by in UnrealScript. The rest of the parameters are the filenames of all your .3ds files. For instance, if you were importing a model called "Gun" with one .3ds file called "Gun.3ds", your 3ds2unr command line would look like this:

Once you've got all this entered properly, hit "OK" and watch 3ds2unr work its voodoo.
3: M o v e F i l e s

Once 3ds2unr is finished, take a look in your "Models" and "Classes" sub-directories, and you'll find three new files waiting for you. In the "Classes" directory will be a .uc file containing the necessary import #execs for your new model. In the "Models" directory will be the actual model files. There will be two of them: ModelName_a.3d, and ModelName_d.3d. Put these two .3d files, along with the .pcx skin for the model, in the Models sub-directory of your mod's project directory (see Using Unreal -make for an explanation about project directories). Next, copy the model #execs into the appropriate UnrealScript class (usually the class that will be using the new model), run Unreal -make, and you're set.


Banes Mutator Tutorial

by Bane

bane@unrealized.com

http://www.unrealized.com

Recently, I made a serious effort in trying to figure out how Unreal's Mutators work. Posts on the Unreal Techpages suggested that some interesting things could be accomplished by using this new, obscure class, yet no matter where I looked, I could find no guidelines of how to actually use them.

During a visit on the IRC, however, I stumbled across Phantal, who had experimented a bit with this new feature. The discussion put me on the right track, so I'd like to extend my thanks for his help.

First of all, let's make it clear that I will only go through the basic use of Mutators in this tutorial - mainly because I'm more or less starting out myself. However, I am aware of the general use of the class(es), so hopefully this doc will help people to get started.

To use a Mutator, you need to inform Unreal that it should add it to the game. The format, expressed as a hyperlink, is:

unreal://map.unr?mutator=mutatorpackage.mutatorclass?game=
gamepackage.gameclass

The various links used within this document are, of course, local ones. If you wish to use Mutators without having to create documents containing a lot of hyperlinks, you may launch "mutated Unreal sessions" (heh) from DOS by replacing "unreal://" with "unreal.exe ". Should you prefer to launch games from within Unreal, bring up the console line and replace the "unreal://" part with "open ".

Why Use Mutators?

Mutators, as the term might suggest, are pretty good at modifying and replacing stuff. Although this can be accomplished by creating a new game type, one of the main advantages of the Mutators is that you don't need a new game type. In fact, you can combine Mutators with any game type, including 3rd party mods.

Another reason to use Mutators is that during network play, the clients will not need to download anything to join, unless the Mutator makes use of actors not shipped with Unreal, of course. So, a player can connect to a server, find himself on a version of Ariza where all weapons have been replaced and/or modified, yet he did not need to download any mod or map to participate. Nifty!

Basic Use of Mutators

Mutators are not game types, nor are they in any way as flexible as game types. If you need to use a special scoring system, custom kill/death rules or whatever, you need to create a new game type. However, if you simply wish to control what items are to be spawned on a level, Mutators are an interesting option.

Mutators are basically replacement classes. They are launched whenever an actor is spawned and by overriding some of the classes found in the standard Mutator class, we can control what items are to be spawned and which ones to scrap. We could also include special checks, such as counters that would allow us to spawn only a specific amount of a certain item. In order to actually use a custom Mutator, we need to instruct the game to use it - this will be covered below.

To create a simple Mutator, we'd want to modify the function CheckReplacement() found in the base Mutator class. This function is called by a Mutator's IsRelevant(), so basically we'd use it to:

  • Check whether or not an item is to be kept or scrapped.
  • Execute replacement code for those items that are to be replaced.

Remember, IsRelevant() is called prior to an item being placed on the level. For those of you not familiar with this function and its GameInfo equivalent, I'll explain the basics, step-by-step:

  1. When a level is loaded and a game is about to start, the engine will attempt to spawn the various actors present on the map. These actors include just about anything - items, triggers, navigation points, pawns and so forth. However, when an actor is about to be spawned, the engine enters the GameInfo's IsRelevant() function to see whether or not it should really create it. In effect, the PreBeginPlay() of any actor includes a call to IsRelevant(), meaning that when IsRelevant() is executed, the actor is yet to appear on the level.
  2. The GameInfo's IsRelevant() immediately calls the current Mutator's IsRelevant() function.
  3. The Mutator's IsRelevant() has the following format: IsRelevant( Actor Other,out byte bSuperRelevant ). "Other" should be pretty obvious - this simply refers to the actor we're currently examining. "bSuperRelevant" is special, however. Although I haven't really used this one myself, my impression is that it is used to override any following replacement attempts - by setting bSuperRelevant to 1, the actor will be kept no matter what (this would include any replacement attempts made by the GameInfo's IsRelevant() as well). However, you need to explicitly support this function in your own Mutators if you wish to use this. Again, it's not something I've bothered using so far.
  4. .The Mutator's IsRelevant() calls another Mutator function - CheckReplacement(). This is where the actual condition checks and replacements take place. If this function removes an actor and/or replaces it with a new one, it should return False. If no changes have been made, it should return True. IsRelevant() will use this return value in step 5 below.
  5. If the Mutator's IsRelevant() returns True, the engine will run the rest of the code in the GameInfo's IsRelevant() function. If, however, it returns False, the function will be exited and the actor will be destroyed.

Creating a Simple Mutator

Confused? Well, it's not that hard, really. To clarify things a bit, have a look at the following, very basic example. To test it, you need to include the Mutator in the command line. Click on this link to try it out: unreal://dmariza.unr?mutator=ASMDMutator.ASMDMutator?game=
UnrealShare.DeathmatchGame.

Now for the actual code. It's intentionally been kept simple and will turn any Unreal map during any game type into an ASMD fragfest.

//===========================================================

// ASMDMutator.

//===========================================================

class ASMDMutator expands Mutator;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)

{

if ( Other.IsA('Weapon') && Other.class!=class'UnrealShare.ASMD' ) {

ReplaceWith(Other, "UnrealShare.ASMD");

return False;

} else if ( Other.IsA('Ammo') && Other.class!=class'UnrealShare.ASMDAmmo' ) {

ReplaceWith(Other, "UnrealShare.ASMDAmmo");

return False;

}

return true;

}

What we're doing here is first to check whether or not we're dealing with a weapon and if so replace it with the ASMD. Note that I've included a check to make sure that the weapon we're examining is not an ASMD. Why? Well, as I have previously mentioned, IsRelevant() and CheckReplacement() are executed prior to the item being placed on the level. If we hadn't included this check, we'd enter an infinite loop as the Mutator tries to replace the ASMD with another ASMD, then checks whether it should replace the replacement and realises that it's a weapon and then repeats the whole process.
After replacing a gun, we exit the function and return False to the caller (i.e. IsRelevant() ). This will cause the original item to self-destruct; had we returned True here, we'd end up with both the original item and the replacement, located on the same spot.
If, however, it's not a weapon we're dealing with, the code determines whether or not it's an ammo item. The principle is the same here - we make sure that it's not an ASMD ammo we're dealing with, then replace the original item and exit.

The code above will affect the default gun as well, but probably not in the manner you would expect. As the default gun no longer exists (we are replacing the Dispersion Pistol), you'll end up starting the match without any weapon at all. To fix this, we need to modify another Mutator function - MyDefaultWeapon(). As the Mutator we're creating will exchange all weapons on a level with ASMD's, the function we're going to write will simply return the ASMD's class to the engine, like this:

function Class<Weapon> MyDefaultWeapon()
{

return class'UnrealShare.ASMD';

}

As you can see, it's ridiculously easy to create simple Mutators whose only function is to replace the default gun..

Try it out: unreal://dmariza.unr?mutator=ASMDMutator.ASMDMutator2?game=
UnrealShare.DeathmatchGame

Adding Additional Mutators

One interesting aspect of Unreal's Mutators is that you can link them. By doing so, we can combine several small Mutators and get quite interesting (or disastrous :) results. Consider this small Mutator:

//============================================================
// LimitAmmoMutator.
//============================================================
class LimitAmmoMutator expands Mutator;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{

if ( Other.IsA('Weapon') && Weapon(Other).PickupAmmoCount==Weapon(Other).Default.PickupAmmoCount )

Weapon(Other).PickupAmmoCount=Max(Weapon(Other).PickupAmmoCount*0.5, 1);

else if ( Other.IsA('Ammo') && Ammo(Other).AmmoAmount==Ammo(Other).Default.AmmoAmount )

Ammo(Other).AmmoAmount=Max(Ammo(Other).AmmoAmount*0.5, 1);

return true;

}

This Mutator will halve the amount of ammo found in all guns and ammo pickups. As you can see, you're not limited to simply replacing stuff using Mutators - you can modify the properties as well.
Now, we could combine this new Mutator with our former one, by using something along these lines:

unreal://dmariza.unr?mutator=ASMDMutator.ASMDMutator2,LimitMutator.
LimitAmmoMutator?game=UnrealShare.DeathmatchGame

The resulting game would be a Deathmatch using ASMD's only, with only half the amount of ammo you'd normally expect available.

So, to sum it up - in order to launch several Mutators at once, you simply enter each Mutator in the command line, separated by a comma. Note however that you must not add a blank after the comma (like "Mutator1, Mutator2") - if you do, you're likely to get an error message.

The Akimbo Mutator

The following Mutator uses a 3rd party mod written by yours truly. So, in order to try it out, you need to have the "AkimboDM" mod installed on your system - get it from Weapons of Destruction (http://www.planetunreal.com/wod/). Now, basically this code is quite similar to the ASMD Mutator we've seen previously:

//=============================================================
// AkimboMutie.
//=============================================================
class AkimboMutie expands Mutator;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{

if ( Other.IsA('Weapon') && Other.class!=class'BaneAkimboMag' ) {

ReplaceWith(Other, "AkimboDM.BaneAkimboMag");
return False;

} else if ( Other.IsA('Ammo') ) {

if ( Other.class!=class'UnrealShare.ShellBox' && Other.class!=class'UnrealShare.Clip' ) {

if ( Ammo(Other).ParentAmmo!=None )

ReplaceWith(Other, "UnrealShare.Clip");

else

ReplaceWith(Other, "UnrealShare.ShellBox");

return False;

}

}
return true;

}

function Class<Weapon> MyDefaultWeapon()
{

return class'AkimboDM.BaneAkimboMag';

}

As you can see, the main difference here is the way ammo items are handled. In order to replace original ammo pickup in a proper way, we check whether or not the item has got a "parent". For instance, the parent of the RifleRound is the RifleAmmo class, so in this case we'd replace the RifleRound with a Clip and the RifleAmmo with a Shellbox.

In order to make ammo a bit more scarce, we might want to use the LimitAmmo Mutator. However, when picking up a Shellbox, the game will claim that we've acquired 50 bullets, even though we've actually only received 25. Let's expand the old LimitAmmo Mutator and change this:

//===========================================================
// LimitAmmoMutator2.
//===========================================================
class LimitAmmoMutator2 expands LimitAmmoMutator;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{

Super.CheckReplacement(Other, bSuperRelevant);
if ( Other.class==class'UnrealShare.ShellBox' && Ammo(Other).PickupMessage==Ammo(Other).Default.PickupMessage )

Ammo(Other).PickupMessage="You picked up 25 bullets";

return true;

}

As the Akimbo mags want access to a AkimboDM GameInfo setting called pTimeLimit, it's probably not a good idea to combine the Mutator with any other game type than the AkimboDM. While it would work, it would also generate a whole lot of error messages in the log file, so let's stick to the Akimbo game type. Try out the result by clicking on this (long) link:

unreal://dmcurse.unr?mutator=akimbomutie.akimbomutie,limitmutator.limitammo
mutator2?game=AkimboDM.Akimbo_DM

Note that as the AkimboMutie makes use of a 3rd party mod, we need to include the "AkimboDM" mod as a ServerPackage if we're going to use the Mutator on a server. Read more about how to accomplish this in "Using Mutators on Servers" below.

Generic Mutators

The Mutators we've had a look at so far are pretty specialised Mutators. They do their job, but their job is pretty restricted to one, single thing. You can, however, code much more generic Mutators, for instance by using Default Properties or *.ini files. This is probably preferable if you intend to write a "true" replacer, which will allow you to replace any item with any other item. For instance, we could create a generic "Weapon Mutator", which would read a list from the Mutator's ini (by using config variables) and then replace weapons based upon the info gathered from that list.
However, be careful when swapping slots between two guns. For instance, let's say that we decide to replace all Automags with Stingers and all Stingers with Automags. When the level is loaded, the Mutator gets to work. Let's assume that the first actor it finds is an Automag - the code would then try to replace it with a Stinger. However, as the new Stinger is spawned, the Mutator kicks in again. It finds that Stingers are to be replaced with Automags.. And so on. Make sure that you add condition checks to avoid errors such as this one.

What follows is what could be considered as an early version of a generic weapon Mutator. It's merely given as an example, so I've not included it as a *.u file.

//=============================================================
// BaneWeaponMutator.
//=============================================================
class BaneWeaponMutator expands Mutator config (BaneMutators);

var config string OriginalWeapon[10], ReplacementWeapon[10];
var bool bIgnore;

function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{

local int i;
local class<weapon> wpn;

for (i=0; i<10; i++) {

if (OriginalWeapon[i]!="") {

wpn=class<weapon>(DynamicLoadObject(OriginalWeapon[i], class'Class'));
if (Other.class==wpn) {

if (ReplacementWeapon[i]!="") {

bIgnore=True;
ReplaceWith(Other, ReplacementWeapon[i]);

}
return False;

}

}

}

return true;

}

function bool IsRelevant(Actor Other, out byte bSuperRelevant)
{

if (bIgnore) {

bIgnore=False;
return True;

}

return CheckReplacement(Other, bSuperRelevant);

}

To make this Mutator work, we obviously need two lists of weapons - one containing the original ones (i.e. the standard Unreal guns) and one containing the replacements. Guns that are not to be replaced should not even be included in the list - for instance, this is a perfectly acceptable ini:

[BaneMutators.BaneWeaponMutator]
OriginalWeapon[0]=UnrealShare.AutoMag
ReplacementWeapon[0]=UnrealShare.Eightball

The code above is a bit "dirty", as it uses something that could be considered a hack to avoid the Automag/Stinger problem I mentioned previously. A Boolean variable called bIgnore is set right before the original gun is replaced. A tweak to IsRelevant() causes the code to automatically accept a gun whenever the bIgnore flag is set. Thus, we'll not enter the annoying infinite loop I described. Not that pretty, perhaps, but it seems to work :)

Using Mutators on Servers

If you've made some Mutator that simply modifies standard Unreal actors and/or replaces them with other standard actors, running a "mutated server" shouldn't pose any problems at all. However, if you're starting to use actors not part of the standard Unreal package, you will face some difficulties. A 3rd party gun, for instance, will become invisible on the clients, won't feature any new sounds and so forth, but it still can be used. Now, if the client hasn't previously downloaded the gun, that wouldn't be surprising - unfortunately, the problem persists even if the gun is located on the client's system..! Fortunately, there is a way around this.
By including any actor that is to be used by a Mutator in the ServerPackages list, you'll enable clients to see and use them without any side effects. Although this is a somewhat awkward solution, especially if you use a number of different Mutators on different occasions, it's the only way to solve the problem.

  1. Open Unreali.ini in a text editor.
  2. Scroll down 'til you see a group called "[Engine.GameEngine]"
  3. A few lines below this header, you should see several lines starting with "ServerPackages="
  4. Add a new line for each package you wish to include (e.g. adding "MyMod.u" would require a line reading "ServerPackages=MyMod")

If you want to create a Dedicated Server, all you need to do is to add "-server" at the end of the command line, i.e. "unreal://mymap.unr?mutator=mymod.mymutator?game=gamemod.gameclass -server"

The Limits of Mutators

While Mutators are quite useful, they do have some limits at this time:

  • They can't really replace true game types, nor were they ever intended to.
  • Their usefulness comes from the fact that you can link a number of Mutators and combine them with a game type.
  • Replacing some actors will produce strange results, including critical errors. If the code attempts to refer to the actor by using variables (i.e. a "handle"), stuff might get unpredictable at best. For instance, replacing a Player Pawn isn't a good idea - the GameInfo stores the return value (which is the "handle" referring to the specific player pawn spawned) and as the Mutator in effect destroys the pawn, the handle will become obsolete. Any attempt to refer to the late player pawn, for instance when the code tries to place the player at a respawn point, will fail utterly.

Final Words

Well, this was a quick introduction to Unreal's Mutators. Hopefully, it wasn't too confusing and will help some coders out there to get started :)

If you wish to contact me, you may do so at bane@unrealized.com

Cheers!
Bane


HUD Mutator Tutorial

As you may have noticed, the HUD class has a HUDMutatorvar that can be used to call a Mutator to add features to the HUD. Unfortunately, the normal ModifyPlayer can't be used to set up each player's HUD in a network game. It works fine on the server side, but none of the clients get a modified HUD. This is because calls the MyHUD of players who aren't locally owned always returns a None.

You can however use the SpawnNotify class to catch and modify HUD's (or anything else) when they are spawned. SpawnNotify is called on both client players and server players, so it works for all. Here's how it goes:

Your main mutator should spawn a SpawnNotify Class. The SpawnNotify adds itself to everyone's level object automatically, insuring it gets called when a new object is spawned. Everytime a HUD is created, you catch it in the SpawnNotify Class and spawn a copy of your hud mutator, seting the HUD's HUDMutator variable to this new object. (Or to the NextMutator var of any Mutator already attached to the HUD.)

Here is sampe source code. I have tested the code out - should allow multiple mutators that use this scheme to all link togeather and all work correctly. Please read through carefully, if you have any questions, email me. Feel free to use, modify, or redistribute the source, although I would prefer it if you left some comments in so the next guy can learn from your work.

Special thanks to Necron_99 for pointing out the AddMutator function. Makes this whole thing a lot more straightforward.

/=============================================================================
//  HUDTestMut is jsut a sample of how to get your SpawnNotify Class spawned.
//   This will be the Mutator you select from the Mutator Menu, so make sure
//   you .int file references this, not the HUDMut.
//
//  Andrew "drunken master" Scholer - ascholer@mediaone.net
//=============================================================================

class HUDTestMut expands Mutator;

function PreBeginPlay()
{
      spawn(class'asHUDTest.asHUDNotify');
}

defaultproperties
{
}

//=============================================================================
//  HUDMut is the mutator you will spawn for each actor to handle
//   the PostRender calls. Note that if there is another HUDMutator
//   attached to it it passes on the function call, allowing the
//   other mutator to do its work also.
//
//  Obviously, to coexist well with other HUDMutators, it might be a good
//   idea to make you draw location adjustable. If you display some status
//   indicators, try creating Mod Menu configurable choices between
//   displaying on the right, left or top of screen. That way user can set up
//   a few different HUD modifying mutators and know they won't overwrite
//   each other on screen.
//
//  Andrew "drunken master" Scholer - ascholer@mediaone.net
//=============================================================================

class HUDMut expands Mutator;

simulated function PostRender(canvas Canvas)
{
    //Do your cool stuff here instrad of this test code.

   Canvas.SetPos(50,50);
   Canvas.DrawText("This is a test");

    //If there is someone chained to this Mutator, call them
    // NextMutator is a variable of the Mutator class and will be set
    // up by the AddMutator call below.

    if ( NextMutator != None ) //next mutator is already defined
    {
         NextMutator.PostRender(Canvas);
    }
}

defaultproperties
{
}

/=============================================================================
// SpawnNotify - Actor spawn notification.
//   NB - This happens on the client AND server for replicated actors.
//
//  As many of you may have noticed, trying to get at MyHUD for clients in
//   a network game through ModifyPlayer dosen't work. Instead you have to
//   use a SpawnNotify actor. Once spawned, this guy sits around and intercepts
//   all spawn hotifications of a given class (Selected in default properties).
//   Note the simulated function call - this guy works on both server and clients.
//
//  I added code to allow HUDmutators to chain off one another. This depends
//   on your HUDMutator class having a variable HUDMutator (see HUDMut). If
//   you really don't want to play nice, just can the else statement below.
//   Then only the first mutator in gets to use it's HUD.
//
//  Andrew "drunken master" Scholer - ascholer@mediaone.net
//=============================================================================

class asHUDNotify expands SpawnNotify;

//Called automatically anytime the class you specified in default properites
// is spawned (also called if a subclass of that class is spawned).
//Great way to catch things to modify or replace them - just make sure to use
// if statements to avoid infinite recursion if you replace something by
// spawning a new subclass.

simulated event Actor SpawnNotification( Actor A )
{
    local Mutator tempActor;

    if ( HUD(A).HUDMutator == none ) {
        //If there aren't any HUDMutators attached to the HUD, attach
        // your mutator.
        HUD(A).HUDMutator = spawn(class'asHUDTest.HUDMut',A);
     }
    else
    {
        //If there is a HUDMutator attached to the HUD already, call
        // AddMutator on that hud, passing it a newly spawned mutator
        // of your own. Note that the AddMutator function will
        // automatically seek the end of the mutator chain. (If the
        // one you try to add yourself to has a NextMutator, the
        // function call is passed to that mutator.)
        HUD(A).HUDMutator.AddMutator(spawn(class'asHUDTest.HUDMut',A));
    }

        //Have to return the original actor (the HUD). If we had
        // completely replaced it we would return the replacement.
    return A;
}

defaultproperties
{
    //This selects what class to intercept spawns for.
    ActorClass=class'Engine.HUD'
}


My First Mod

My First Mod (UT Edition)

By Sprint1 (edited by Kobain)

Beginner

(This tutorial assumes you have Unreal Tournament installed to your C:\UnrealTournament directory.) This tutorial explains how to create a very simple mod using the Ripper as a base. It will guide you through the basics of how to create a mod. After you're comfortable with editing everything this tutorial teaches you, you should graduated to Windex's tutorials, or the tutorials at UnrealEd.net. .

This tutorial is for Windows users only; I'm not sure how this will work on a Mac.

Note: Before you start, open your UnrealTournament\System folder and make sure you don't have a file in there called MyMod.u. If you do, rename it or delete it.

1. Make sure you have the latest versions of Unreal Tournament and UnrealEd installed.

2. Open MS-DOS from Windows. Go to your UnrealTournament\System directory, and type this (without quotes):
"ucc batchexport botpack.u class uc c:\UnrealTournament\Reference\"
This should export everything inside botpack.u into a new folder in your UT directory called Reference.

3. Make a folder inside your UnrealTournament directory called "MyMod". Now open the MyMod folder, and inside there, make another folder called "Classes".

4. Open C:\UnrealTournament\System\UnrealTournament.ini. Find the [Editor.EditorEngine] section, and go to the bottom of it where it has a bunch of lines starting with EditPackages. Create a new line just under the EditPackages that reads:
"EditPackages=MyMod"

5. Copy the Ripper.uc file from your UnrealTournament\Reference folder to your UnrealTournament\MyMod\Classes folder.

6. From the UnrealTournament\MyMod\Classes folder, open Ripper.uc with NotePad. You'll see the coding for the Ripper. Don't touch anything unless I tell you to!

7. First, delete all the lines that start with #. This will get rid of some ugly warnings when you compile the code later. Those lines were just used when importing the original UT models.

8. Scroll down to the defaultproperties section. See the lines that start with "ProjectileClass" and "AltProjectileClass"? Those are the primary and alternate fire mode projectiles, and that's what we're going to change. Change them to look like these:

ProjectileClass=Class'botpack.RocketMk2'
AltProjectileClass=Class'botpack.ut_grenade'

If you open the ut_eightball.uc file and scroll down, you'll see where these are from.

9. Go up to the very top of the code. You should see "class Ripper extends TournamentWeapon". Change the word Ripper to RL. Above this line, you should see three lines with double slashes starting them. Anything with double slashes at the beginning of the line is a comment, and Unreal will ignore it for the purposes of coding. You can use the // comment anywhere in your code (it has to start a line) to remind yourself of certain things if you want.

10. From your UnrealTournament\MyMod\Classes\ folder, rename the Ripper.uc file in there to RL.uc. The title of the .uc file should always match the name of the weapon, i.e. what you type in the "____ extends TournamentWeapon" line.

11. You can finally close any Unreal-related files or folders you have left open, except this tutorial. (Unless you've printed it out, which is probably a better idea.)

12. Open MS-DOS from Windows and go to your UnrealTournament\System directory. Type this (no quotes):
"ucc make"

UCC will run through every EditPackage (as defined in UnrealTournament.ini), and make sure there's a .u file for every one of them. If there isn't, it'll try to compile it. Since you defined MyMod as an editpackage earlier, and you don't have a MyMod.u file in your System folder, it'll start compiling everything in MyMod\Classes.

Note: The number one complaint I get about this tutorial is that UCC doesn't find the MyMod package. (Actually it's more like "ucc cant find my mod it cant be my falt becuz i am l33t". ;P) Make SURE you followed the directions in steps 3 and 4, and also check to see if you have a file in your UnrealTournament\System directory called MyMod.u. If you do, delete it or rename it.

13. Now for the sweet part. Open up Unreal Tournament and start a practice game. From the console, type "iamtheone" to enable cheats, and then "summon mymod.rl" (no quotation marks either time). You should see what looks like a Ripper floating in front of you. Pick it up, and fire it. Congratulations, you've made your first mod!

14. Go ahead and edit other things in RL.uc, starting with the defaultproperties. Once you're good with that, start working on the main part of the code. Just remember that before you compile MyMod again, you'll have to delete MyMod.u from your UnrealTournament\System directory. Have fun!


My First Mod Part 2

By Sprint1 (edited by Kobain)

Beginner

(This tutorial assumes you have Unreal installed to your C:\Unreal directory.) This was originally a tutorial Sprint1 wrote way back when he was the web master at WoD. Now that he's passed on the throne, I've brought it back. It's for Unreal, but with minimal alterations, applies to Unreal Tournament.

So you've finished your insanely powerful Rocket Launcher from the first tutorial, and are hungry for more "easy-editing"? Here's an explanation of what everything in the defaultproperties of the Stinger means.

Everything in NAVY is the actual code, and everything in GREEN is my explanation.

defaultproperties
{
AmmoName=Class'UnrealShare.StingerAmmo'
This is the Ammo Type that the weapon will use. Check out other weapons for more ammo types.
PickupAmmoCount=40
How much "AmmoName" ammo you get when you pick up the weapon.
bAltWarnTarget=True
This is when you put the crosshair over the enemy. For a bot they would spring into action and start going crazy at you, or at a player it would make that noise if you get locked on by the 8ball.
FireOffset=(X=12.000000,Y=-10.000000,Z=-15.000000)
It may look like the projectile comes out of the model, but it actually spawns at this point in the radius of the player.
ProjectileClass=Class'UnrealShare.Rocket'
This is the projectile that is fired when the Fire button is pressed. If you want to see other projectiles, look under "Projectiles" in the UnrealEd Classes menu.
AltProjectileClass=Class'UnrealShare.Rocket'
This is the projectile that is fired when the AltFire button is pressed.
shakemag=120.000000
This is how much the weapon shakes when it is called to shake. And that's usually when the weapon fires.
AIRating=0.400000
This is the rating of the weapon for bots. If its higher they worship it, lower and its something they bought in the local radioshack sale.
RefireRate=0.800000
This is how fast the weapon fires in primary fire. Higher is faster, but try not to go past 1.000000. For the Stinger, you may have to modify the Sleep counts in the main code, which right now are set at 0.2 for primary fire and 1.0 for alternate fire.
FireSound=Sound'UnrealShare.Stinger.StingerFire'
AltFireSound=Sound'UnrealShare.Stinger.StingerAltFire'
SelectSound=Sound'UnrealShare.Stinger.StingerLoad'
Misc1Sound=Sound'UnrealShare.Stinger.EndFire'
These are a list of all the sounds the weapon makes. There are so many sounds in the game that I can't even begin to make a list, but check out every class you can find and copy the sounds from them.
DeathMessage="%o was perforated by %k's %w."
This looks more complicated than it actually is. See, this is the message that pops up when you kill someone with this weapon. %o means it will print the person's name that was killed. %k is the killer (k=killer, that's easy), and %w is the weapon used by %k to kill %o. The weapon's name is determined by the ItemName, shown below.
AutoSwitchPriority=3
After a weapon runs out of ammo, it checks which weapon has the highest AutoSwitchPriority, and goes to it. You can change a weapon's default AutoSwitchPriority temporarily by going to your Options menu in Unreal.
InventoryGroup=3
This is pretty self explanatory. When you press 3, it will change to this weapon. But if you change this, the ammo the weapon uses won't match up in the weapon inventory screen, which doesn't really cause a problem except when you want to see how much ammo you have in a weapon without actually switching to it.
PickupMessage="You picked up the Stinger"
This is the message you get when you pick up the weapon. You can change it to anything you want, but keep it easy enough for the person to know what weapon it is.
ItemName="Stinger"
This is used in the DeathMessage and a few other things. Make sure it's the actual name of your weapon, and nothing else.
PlayerViewOffset=(X=4.200000,Y=-3.000000,Z=-4.000000)
How the player views the model. X right/left, Y is out/in, and Z is up/down. It mostly takes trial and error to get this right, unless you can think in 3D.
PlayerViewMesh=LodMesh'UnrealShare.StingerM'
The model the player sees. Again, there are a huge number of meshes in Unreal, so I can't make a list. But in UnrealEd, open the Windows tab, and then the Mesh Viewer tool.
PlayerViewScale=1.700000
The size of the mesh the player sees. By default, the Stinger is multiplied by 1.7, but 1.0 is "normal" size.
PickupViewMesh=LodMesh'UnrealShare.StingerPickup'
The model seen when the weapon is floating around, waiting to be picked up.
ThirdPersonMesh=LodMesh'UnrealShare.Stinger3rd'
The model seen in third person, i.e. when you are holding the weapon, or are seeing someone else holding the weapon.
PickupSound=Sound'UnrealShare.Pickups.WeaponPickup'
The sound played when you pickup the weapon. WeaponPickup is used for most weapons.
Mesh=LodMesh'UnrealShare.StingerPickup'
Mesh is declared in all classes. Because its a weapon in run time it changes to pickup mesh, so you only use it for what it looks like in the editor.
bNoSmooth=False
If this is True, the model won't be smoothed, and it'll look strange. Keep it false so the model looks better.
SoundRadius=64
How far the sounds travel, starting from the gun and ending 64 units out in each direction.
SoundVolume=255
The volume of the sounds. Note that in the main body of the code, this is multiplied by a certain amount for each sound the weapon makes, and it's also influenced by whether or not you have the Silencer.
CollisionRadius=27.000000
How far around the player the weapon collides with the world. Keep this amount so the player can actually move. :)
CollisionHeight=8.000000
How far above the player the weapon collides with the world.
}


rogerbacon2

Creating new skin files

by Roger Bacon

1 - DRAWING THE SKIN

- Download the template skins HERE:
The templates basically show a low contrast version of an existing skin - the black thunder skin for the 'male soldier' model. I've overlayed a skinmesh over the top so you can see the models wireframe.
(PRO) If you want to see the texture on the model as you create it, download THIS FILE (provided by Shane Caudle). Its a MAX scene of the soldier dude, with a single texture. This means you have to chop the texture up into 4 when you are done, but its worth it. This also means you can use 3d painters like meshpaint, painter3d, deep paint3d, etc if thats what you like.

- Rename the first 4 letters (xxxx) of all files to anything you want as long as its 4 letters. for this example i will rename them 'rogx'.
Also change the 'name' part of the last two pcx's to a suitable name for the face of your skin. I now have:

rogx1.pcx (The chest and arms)
rogx2.pcx (The Thighs and Boots)
rogx3.pcx (The shoulders and arms)
rogx4.pcx (The default face skin)
rogx4sixes.pcx (A face belonging to 'Sixes')
rogx5sixes.pcx (Sixes' portrait file for the chat messages)

(PRO) Note the files with 'sixes' in the name are additional face files. If i wanted to do another selectable face for my skin (i'll call him 'Bob') I would add 2 more files :- rogx4bob.pcx, and rogx5bob.pcx.

- Draw over them in the manner you see fit (hey, you're the artist!)
However know this - Each of the 5 pcx's has its own 256 color palette. You could have 256 shades of red on the arms and 256 shades of green on the legs if you so desire....
(PRO) make sure its Version 5 PCX or else you wont get 256 colours...

- Once you are sure they are top quality, start UNREALED

Step 2 : Importing the PCX's


rogerbacon3

Creating new skin files pt.2

by Roger Bacon

2 - IMPORTING THE TEXTURES

- Make sure 'Textures' is selected in the dropdownlist on the toprighthand side of the screen.

- click the 'new' button at the bottom to create a new texture package.

- enter anything as the name (I use 'deleteme') to create a temporary file, but call the the package what you want the skifile to be called. i called mine 666skins

- Click the Import button, then select all the pcx's of your new skin. They should now appear in the window on the right.

- Delete the (deleteme) file as you dont need it anymore

- Click Save to save the package.. use the same name as the one you used earlier. I called mine: 666skins.utx

- Close UNREALED as you dont need it anymore.

- This is a wierd bit. Now you have to rename the package to a one with 'soldierskins_' preceeding it. So in explorer I now rename my file to Soldierskins_666skins.utx

- Its not over yet.... Now you need to make a file that lets UT know where to get your new skin from, which is called an INT file.

back to Step 1:

Step 3 :Create the INT


rogerbacon4

Creating new skin files pt. 3

by Roger Bacon

3 - REFERENCING YOUR NEW SKIN

- Create a file in your UnrealTournament \ SYSTEM directory using the same name as your package (ie Soldierskins_666skins.INT)

- Copy and paste the text below into your INT file. Then edit the names of the skins to match your package and skin names. When you have finished save and close the INT. Wasnt that part easy? ;)

[public]
Object=(Name=soldierskins_666skins.rogx1,Class=Texture,Description="Rogmeistah")
Object=(Name=soldierskins_666skins.rogx2,Class=Texture)
Object=(Name=soldierskins_666skins.rogx3,Class=Texture)
Object=(Name=soldierskins_666skins.rogx4,Class=Texture)
Object=(Name=soldierskins_666skins.rogx4Sixes,Class=Texture,Description="666")
Object=(Name=soldierskins_666skins.rogx5Sixes,Class=Texture)

- Now the UT server needs to be told to include the INT file you have just created. (else it wont show up in the player setup screen)
Open UnrealTournament.INI and look for the section that holds lines that look like these:

.........
ServerPackages=SoldierSkins
ServerPackages=CommandoSkins
ServerPackages=FCommandoSkins
ServerPackages=SGirlSkins
ServerPackages=BossSkins

Yours might look slightly differend depending on whether or not you have been installing new skins or mutators but this doesnt matter. Pop a line underneath that is exactly the same but references your new skin INT. Mine now looks like this:

...........
ServerPackages=SoldierSkins
ServerPackages=CommandoSkins
ServerPackages=FCommandoSkins
ServerPackages=SGirlSkins
ServerPackages=BossSkins
ServerPackages=Soldierskins_666Skins

AND THATS IT! Hopefully (fingers crossed), you should now be able to select your new skin in the Player setup screen. However, with this many steps to follow there is an equal amount of places to go totally wrong......
It took me a while to get a test skin working (I kept screwing up) so keep at it and follow the steps carefully.

GOOD LUCK!

Back to Step 2


 Script Class Tree

The class browser in UED has quite the hierarchy going on. This is a quick and easy reference to figure out where something is.

 B r u s h
   Mover
      AssertMover
      AttachMover
      ElevatorMover
      GradualMover
      LoopMover
      MixMover
      RotatingMover

 D a m a g e T y p e
   UnrealDamageType
      Burned
      Corroded
      decapitated
      drowned
      fell

 D e c o r a t i o n
   Barrel
   Book
      BlueBook
      GreenBook
      YellowBook
   Boulder
   BubbleGenerator
   Candle
   Candle2
   Cannon
      HugeCannon
   Carcass
      CreatureCarcass
         BruteCarcass
            LesserBruteCarcass
         CowCarcass
            BabyCowCarcass
         DevilfishCarcass
         FlyCarcass
         GassiusCarcass
         HumanCarcass
            DeadMales
               MaleBody
                  MaleOneCarcass
                  thrownbody
               MaleBodyThree
                  MaleThreeCarcass
               MaleBodyTwo
                  DeadChairMale
                  MaleTwoCarcass
            FemaleBody
               Female2Body
                  FemaleTwoCarcass
               FemaleOneCarcass
            FemaleTorso
         KrallCarcass
         MantaCarcass
         MercCarcass
         NaliCarcass
            CrucifiedNali
         PupaeCarcass
         QueenCarcass
         SkaarjCarcass
         SlithCarcass
         SquidCarcass
         TentacleCarcass
         TitanCarcass
         TrooperCarcass
         WarlordCarcass
      CreatureChunks
         MasterCreatureChunks
            femalemasterchunk
            MaleMasterChunk
            NaliMasterChunk
            SkaarjMasterChunk
            troopermasterchunk
         PlayerChunks
            Arm1
            FemaleHead
            Leg1
               Leg2
            Liver
            MaleHead
            PHeart
            Stomach
            Thigh
   Chair
   Chest
   Cryopod
   Dice
   DripGenerator
      Drip
   EscapePod
   Fan2
   Flag1
      Flagb
   Flag2
   Flag3
   InterpolatingObject
   IntoShip
   Knife
   Lamp1
   Lamp4
   Lantern
   Lantern2
   MonkStatue
      NaliStatue
   Moon
      Moon2
      Moon3
   Panel
   Plant1
   Plant2
   Plant3
   Plant4
   Plant5
   Plant6
   Plant7
   Robot
   ScaledSprite
   Sconce
   SeaWeed
   Sign1
   SludgeBarrel
   SteelBarrel
      TarydiumBarrel
   SteelBox
      SmallSteelBox
   Table
   Tapestry1
   Tree
      Tree1
      Tree10
      Tree11
      Tree12
      Tree2
      Tree3
      Tree4
      Tree5
      Tree6
      Tree7
      Tree8
      Tree9
   Urn
   Vase
      Pottery0
      Pottery1
      Pottery2
   Wire
      SmallWire
   WoodenBox
      MedWoodBox
      SmallWoodBox

 E f f e c t s
   AnimSpriteEffect
      DefaultBurst
         DefaultBurstAlt
      EnergyBurst
      FlameExplosion
      SmokeColumn
      SmokeExplo
      SpriteBallExplosion
         SilentBallExplosion
         SpriteBallChild
         SpriteBlueExplo
            SpriteGreenE
            SpriteOrangeE
            SpriteRedE
            SpriteYellowE
      SpriteLightning
      SpriteSmokePuff
         BigBlackSmoke
         BlackSmoke
         BloodPuff
         GreenSmokePuff
            GreenBloodPuff
            GreenGelPuff
         RisingSpriteSmokePuff
         WallHitEffect
            HeavyWallHitEffect
            LightWallHitEffect
   ArrowSpawner
   BallExplosion
   Blood2
      BloodBurst
      BloodSpray
      BloodSpurt
      BloodTrail
   BloodPool
   Bubble
   Bubble1
   BulletHit
   Chip
   DExplosion
   Electricity
   ExplodingWall
      BreakingGlass
   ExplosionChain
   FatRing
   Flame
   FlameBall
   GreenBlob
   MercFlare
   ParticleBurst
      ParticleBurst2
   PawnTeleportEffect
      QueenTeleportEffect
   QueenShield
   ReSpawn
   RingExplosion
      RingExplosion2
      RingExplosion3
      RingExplosion4
      WaterRing
   Shield
   SmallSpark
      SmallSpark2
      Spark3
         Spark32
         Spark33
         Spark34
         Spark35
   SmokeGenerator
      ShortSmokeGen
   SmokeHose
   SmokeHoseDest
   SmokePuff
   SmokeTrail
   SparkBit
   Sparks
   SpikeExplosion
   splash
   SpriteExplosion
   Tazerexplosion
   TinyBurst
   TSmoke
   WaterImpact

 H U D
   UnrealHUD
      EndgameHud
      IntroNullHud
      spectatorhud
      UnrealTeamHUD

 I n f o
   BotInfo
   CodeMaster
   GameInfo
      UnrealGameInfo
         CoopGame
         DeathMatchGame
            DarkMatch
            KingOfTheHill
            TeamGame
         EndGame
         EntryGameInfo
         Intro
         SinglePlayer
         VRikersGame
   InternetInfo
      InternetLink
         TcpLink
         UpdLink
            UdpBeacon
               ClientBeaconReceiver
            UdpServerQuery
            UdpServerUplink
   MapList
      DKmaplist
      DMmaplist
   ReplicationInfo
      GameReplicationInfo
      PlayerReplicationInfo
   SavedMove
   TeamInfo
   TestInfo
      UnrealTestInfo
   VoicePack
   ZoneInfo
      CloudZone
      LavaZone
      LevelInfo
      NitrogenZone
      SkyZoneInfo
      SlimeZone
      TarZone
      TeleporterZone
      ToggleZoneInfo
      WarpZoneInfo
      WaterZone

 I n v e n t o r y
   Pickup
      Ammo
         ASMDAmmo
            DefalutAmmo
         FlakBox
            FlakShellAmmo
         NullAmmo
         RazorAmmo
         RifleAmmo
            RifleRound
         RocketCan
         ShellBox
            Clip
         Shells
         Sludge
         StingerAmmo
      Amplifier
      Armor
      Dampener
      Flare
      Flashlight
         SearchLight
      ForceField
      Health
         Bandages
         NaliFruit
         SuperHealth
      Invisibility
      JumpBoots
      SCUBAGear
      Seeds
      ShieldBelt
         PowerShield
      Suits
         AsbestosSuit
         KevlarSuit
         ToxinSuit
      Translator
      VoiceBox
      WeaponPowerUP
   Weapon
      ASMD
      AutoMag
      DispersionPistol
      Eightball
      FlakCannon
      GESBioRifle
      Minigun
      QuadShot
      Razorjack
      Rifle
      Stinger

 K e y p o i n t
   AmbientSound
   BlockAll
   BlockMonsters
   BlockPlayer
   DynamicAmbientSound
   Earthquake
   GuardPoint
   InterpolationPoint
      TimeDemoInterpolationPoint
   MakeNaliFriendly
   ObjectPath
   PathPoint
   Rockslide
      MagmaBurst
   ThingFactory
      CreatureFactory
   ThrowStuff
   TriggeredAmbientSound
   WayBeacon

 L i g h t
   ChargeLight
   DistanceLighting
   FlashLightBeam
   OverHeatLight
   QueenTeleportLight
   SightLight
   SpotLight
   TorchFlame
   TriggerLight
   TriggerLight
   TriggerLightRad
   WeaponLight
      EffectLight
      PurpleLight

 M e n u
   UnrealMenu
      InfoMenu
      UnrealInfoMenu
         OKMenu
         YesNoMenu
            UpgradeMenu
      UnrealListMenu
      UnrealLongMenu
         UnrealBotConfigMenu
         UnrealChooseGameMenu
         UnrealFavoritesMenu
         UnrealGameMenu
            UnrealNewGameMenu
         UnrealGameOptionsMenu
            UnrealCoopGameOptions
            UnrealDMGameOptionsMenu
               UnrealTeamGameOptionsMenu
         UnrealHelpMenu
         UnrealJoinGameMenu
         UnrealKeyboardMenu
         UnrealListenMenu
         UnrealMainMenu
         UnrealMultiPlayerMenu
         UnrealOptionsMenu
         UnrealQuitMenu
         UnrealServerMenu
         UnrealSlotMenu
            UnrealLoadMenu
            UnrealSaveMenu
         UnrealVideoMenu
         UnrealWeaponMenu
      UnrealShortMenu
         UnrealIndivBotMenu
         UnrealPlayerMenu
            UnrealMeshMenu

 N a v i g a t i o n P o i n t
   AlarmPoint
   AmbushPoint
   ButtonMaker
   HomeBase
   InventorySpot
   LiftCenter
   LiftExit
   PathNode
   PatrolPoint
   PlayerStart
   QueenDest
   Spawnpoint
   Teleporter
      FavoritesTeleporter
   Transporter
   TriggerMarker
   WarpZoneMarker

 P a w n
   Bots
      HumanBot
         FemaleBot
            FemaleOneBot
            FemaleTwoBot
         MaleBot
            MaleOneBot
            MaleThreeBot
            MaleTwoBot
         SkaarjPlayerBot
   FlockMasterPawn
      BiterFishSchool
      HorseFlySwarm
         DeadBodySwarm
      ParentBlob
   FlockPawn
      Bird1
      BiterFish
      Bloblet
      HorseFly
      NaliRabbit
   PlayerPawn
      Camera
      Spectator
         UnrealSpectator
      UnrealIPlayer
         Human
            Female
               FemaleOne
               FemaleTwo
            Male
               MaleOne
               MaleThree
               MaleTwo
         SkaarjPlayer
      Scout
   ScriptedPawn
      Brute
         Behemoth
         LesserBrute
      Cow
         BabyCow
      DevilFish
      Fly
      Gasbag
         GiantGasbag
      Krall
         KrallElite
         LeglessKrall
      Manta
         CaveManta
         GiantManta
      Mercenary
         MercenaryElite
      Nali
         NaliPriest
      Pupae
      Queen
      Skaarj
         SkaarjTrooper
            SkaarjGunner
            SkaarjInfantry
            SkaarjOfficer
            SkaarjSniper
         SkaarjWarrior
            IceSkaarj
            SkaarjAssassin
            SkaarjBerserker
            SkaarjLord
            SkaarjScout
      Slith
      Squid
      Tentacle
      Titan
         StoneTitan
      WarLord

 P r o j e c t i l e
   Arc
   Arrow
   BigRock
      Boulder1
      Magma
   BioGel
      BarrelSludge
      BigBiogel
      Biodrop
   BruteProjectile
      MercRocket
   Chunk
      Chunk1
         MasterChunk
      Chunk2
      Chunk3
      Chunk4
   DispersionAmmo
      DAmmo2
      DAmmo3
      DAmmo4
      DAmmo5
   EnergyBolt
   FlakShell
   ForceFieldProj
   Fragment
      Fragment1
      GlassFragments
      WallFragments
      WoodFragments
   GasBagBelch
   Grenade
   KraalBolt
      CannonBolt
      EliteKrallBolt
   PeaceRocket
   Plasma
   RazorBlade
      RazorBladeAlt
   Rocket
      SeekingRocket
   ShellCase
   SkaarjProjectile
      QueenProjectile
   SlithProjectile
   StingerProjectile
   TazerProj
   TentacleProjectile
   Tracer
   WarlordRocket

 S c o r e B o a r d
   UnrealScoreBoard
      UnrealTeamScoreBoard

 T r i g g e r s
   CodeTrigger
   Counter
   Dispatcher
   ElevatorTrigger
   FatnessTrigger
   FearSpot
   Jumper
   MusicEvent
   RoundRobin
   SpecialEvent
   StochasticTrigger
   TranslatorEvent
   Trigger
      ZoneTrigger
   TriggeredDeath


Script Functions

A l t F i r e ( )
Defined In: Weapon

Called By: Engine

Return Type: None

Parameters: float Value

Called by the engine when the player presses the alt-fire button.

D e s t r o y ( )
Defined In: Actor

Called By: Programmer

Return Type: bool

Parameters: None

Used to destroy an actor in the Unreal world. It will return a bool value saying whether or not Unreal was able to destroy the actor.

D e s t r o y e d ( )
Defined In: Actor

Called By: Engine

Return Type: None

Parameters: None

Called by the engine when an actor is destroyed. Useful for tying up any loose ends before something is removed from existence.

F i n i s h ( )
Defined In: Weapon

Called By: Programmer

Return Type: None

Parameters: None

Used to finish a firing sequence. Be careful about forgetting to call this. Many times, a weapon will lock up without it.

F i n i s h A n i m ( )
Defined In: Actor

Called By: Programmer

Return Type: None

Parameters: None

A latent function that will pause execution of state code until the current animation of the actor's model is finished playing.

F i r e ( )
Defined In: Weapon

Called By: Engine

Return Type: None

Parameters: float Value

Called by the engine when the player presses the fire button.

H i t W a l l ( )
Defined In: Actor

Called By: Engine

Return Type: None

Parameters: vector HitNormal
actor HitWall

Called by the engine when an actor hits the level. Useful for spawning collision effects.

H u r t R a d i u s ( )
Defined In: Actor

Called By: Programmer

Return Type: None

Parameters: float DamageAmount
float DamageRadius
name DamageName
float Momentum
vector HitLocation

Used to inflict damage on anything within a certain radius. DamageAmount is the amount of damage that will be inflicted on anything at the center of the radius, DamageRadius is the radius (in Unreal units) of the damage, DamageName is a word that describes the damage inflicted (such as 'burned' or 'corroded'), Momentum is the force with which things taking damage will be thrown away from the center of the radius, and HitLocation is the location of the radius center.

I s A ( )
Defined In: Actor

Called By: Programmer

Return Type: bool

Parameters: name ClassName

Returns true if the actor it's called from is the same class as ClassName.

L a n d e d ( )
Defined In: Actor

Called By: Engine

Return Type: None

Parameters: vector HitNormal

Called by the engine when an actor hits a floor. Useful for spawning effects.

L o o p A n i m ( )
Defined In: Actor

Called By: Programmer

Return Type: None

Parameters: name Sequence
optional float Rate
optional float TweenTime
optional float MinRate

Used to loop one of an actor's model animations.

P l a y A n i m ( )
Defined In: Actor

Called By: Programmer

Return Type: None

Parameters: name Sequence
optional float Rate
optional float TweenTime

Used to play one of an actor's model animations.

P l a y S o u n d ( )
Defined In: Actor

Called By: Programmer

Return Type: None

Parameters: sound Sound
ESoundSlot Slot
float Volume
bool bNoOverride
float Radius
float Pitch

Used to play a sound from the actor's location.

P o s t B e g i n P l a y ( )
Defined In: Actor

Called By: Engine

Return Type: None

Parameters: None

Called by the engine immediately after gameplay begins.

P r e B e g i n P l a y ( )
Defined In: Actor

Called By: Engine

Return Type: None

Parameters: None

Called by the engine immediately before gameplay begins.

P r o c e s s T r a c e H i t ( )
Defined In: Weapon

Called By: Engine

Return Type: None

Parameters: Actor Other
Vector HitLocation
Vector HitNormal
Vector X
Vector Y
Vector Z

Called when a weapon's TraceFire hits something. Useful for spawning any collision effects, or doing damage to actors.

S e t B a s e ( )
Defined In: Actor

Called By: Programmer

Return Type: None

Parameters: actor NewBase

Used to set a new mover base for an actor.

S e t L o c a t i o n ( )
Defined In: Actor

Called By: Programmer

Return Type: bool

Parameters: vector NewLocation


Scripted Textures

by Tag (From Tag's site, currently custody of Postal)

Advanced

Muchos Thankiosos to Jack Porter for explaining this all to me. I had asked him pre-220 if it would be possible in Unreal Tournament to create an in-level scoreboard for my UnrealBall mod, and he told me about this class. He also told me it would be available in Unreal in the next patch.

When I discovered the ScriptedTexture class was indeed buried away in Unreal 224, I again wrote Jack and asked for a quickie "Idiot's Guide to Creating Scripted Textures", to which he obliged almost instantly. His written instructions worked like a charm, and are basically paraphrased below. I expanded a bit in a few areas and used references to the downloadable example.

The ScriptedTexture class is an ancestor of Texture, which itself is under Bitmap. If you are a UnrealScript programmer, and you export all of your .U files to .UC text files, then you should have file ScriptedTexture.uc in your engine\classes folder under your Unreal main folder.

If you wanted to study the class inside UnrealEd, you have to check off "Only Show Actor Classes", since the Bitmap class is not under Actor, it's under Object.

Object->Bitmap->Texture->ScriptedTexture

Studying this class will yield the main clues as to how it works. There are two variables declared, one as a design-time and one as a run-time variable. They are as follows:

var Actor NotifyActor;
this run-time property is set to some custom class that you will write later that will handle the drawing on your texture.

var() Texture SourceTexture;
this design-time variable will point to the Scripted texture class that you will wish to draw on.

Also inside the class are four functions DrawTile, DrawText, DrawColoredText, and ReplaceTexture. I haven't played with each one yet, but I'm assuming they are fairly self-explanatory.
What follows is a tutorial on creating a simple implementation of a scripted texture, one that displays a small message on the texture. The message cycles between four colors and bounces a bit inside the texture, just to prove that it's happening in real-time.
Step 1: Create a "border" texture.

Using PhotoShop or whatever image-editing program you prefer, create the texture that will serve as the "page" that your scripted texture will draw on. My base texture for this demo is a blue frame around a black field. I gave the frame a little 3d effect in PhotoShop.

Step 2: Import the texture into UnrealEd.

Again, same basic rules apply here, nothing out of the ordinary. Import the texture into the package of your choice. One caution: make sure the 256 color palette of the image contains all of the possible colors that you will use to draw upon the texture. Remember that each individual brush surface uses a palettized, 256 color texture. If you have a palette of 256 shades of blue on your border texture, and wish to draw red text on it, you won't get the desired effect.

In the downloadable demo, the border texture is named STBORDER.

Step 3: Create the ScriptedTexture

You do this the same way you create a procedural texture (FireTexture, WaterTexture, etc). Put this texture in the same package as the border texture you created above, and make it the same size as the border texture (Of course, give it a different name as the border texture). Then, right click on the ScriptedTexture to bring up its properties, and make the property "SourceTexture" point to your border texture.

In the downloadable demo, the ScriptedTexture's name is SCRIPTBORDER, and it points to texture STBORDER described above.

If you do this correctly, the border texture and the scriptedtexture will look exactly the same in the texture preview window of UnrealEd.

Step 4: Create the Base "Communicator" Class.

This is the base class that you will code your scripted code into. The class shown below need only be created once for ALL your scripted textures. To create different types of classes, inherit off of this base class.

class ClientScriptedTexture expands Info;
var() Texture ScriptedTexture;
simulated function BeginPlay()
{
if(ScriptedTexture != None)
ScriptedTexture(ScriptedTexture).NotifyActor = Self;
}
simulated function Destroyed()
{
if(ScriptedTexture != None)
ScriptedTexture(ScriptedTexture).NotifyActor = None;
}
simulated event RenderTexture(ScriptedTexture Tex)
{//implement in subclass
}
defaultproperties
{
RemoteRole=ROLE_SimulatedProxy
bStatic=False
bAlwaysRelevant=True
bNoDelete=True
}
Step 5: Create the specific "Communicator" Class.

Inherit a new class off of ClientScriptedTexture above. This specific class is where you will put all of the code for this scriptedtexture effect. In my demo, I created a string property that the level designer can enter, and the string will be drawn on the texture surface. It will both bounce from left to right and cycle between red, green, blue, and yellow. The code for this class is below

class stBannerAd
                    expands
                    ClientScriptedTexture;

var(ClientScriptedTexture)
                    string AdvertisingText;

var int nX;
var int
                    nDelta;
                    //move direction

simulated function
                    BeginPlay()
{
Super.BeginPlay();
nX =
                    16;
                    //init x location
nDelta =
                    1;
}

simulated event RenderTexture(ScriptedTexture
                    Tex)
{
local color clr;
local int nSec;

nSec
                    = Level.TimeSeconds % 4;
if (nSec == 0)
                    {
clr.r = 0;
clr.g = 0;
clr.b = 255;
} else if
                    (nSec == 1) {
clr.r =
                    255;
clr.g = 0;
clr.b = 0;
} else if (nSec == 2) {
clr.r = 0;
clr.g =
                    255;
clr.b = 0;
} else
                    {
clr.r = 255;
clr.g = 255;
clr.b =
                    0;
}

nX += nDelta;

if (nX < 16)
                    {        //change
                    direction
nX =
                    16;
nDelta =
                    1;
}

if (nX > 78)
                    {        //change
                    direction
nX =
                    78;
nDelta =
                    -1;
}

Tex.DrawColoredText(
                    nX, 28, AdvertisingText, Font'WhiteFont', clr
                    );

}
The main function is of course RenderTexture, which passes in the surface that it to be rendered. My little demo figures out which color to draw the text in, based on the number of seconds elaped in the level. It then adds internal value Delta to nX, which is the starting left position for the text, and then checks to see if the direction should be switched (my demo is hardcoded to a value of 78 to bounce on the right side, which will only look good for strings the same length as my demo string, which is "http://www.planetunreal.com/". A better class would check the length of the string and figure out the right bounce amount.

Finally, RenderTexture calls DrawColoredText with the appropriate parameters.

Step 6: Set it all up in a map

The last step is to just put all of these pieces together in a map. Create some brushes and put the ScriptedTexture on their surface (make sure to use the ScriptedTexture and not the Border Texture, since they do look exactly like. Giving them easily distinguishable names will help here).

Then, create an instance of your specific "communicator" class somewhere on the map. Make sure that its ScriptedTexture property is equal to the Scripted Texture that you created (the same one you just put on the brush surfaces).


Mutator Appendix

Squidi's Guide to Making Mutators

Now to the fun part. Explaining the Mutator class. The class descends from Info, which
is an Actor, and so Mutator inherits all of these variables and properties. It doesn't
use most of them, but some of them, such as Actor's Tick() function, can be useful.
Anyway, on to the explaining.

Variables
 ----------------- bool bHUDMutator;
This variable is set to true when RegisterHUDMutator() succeeds. Defaults to false.
Don't bother setting this variable. It's only use is as listed.
class

 DefaultWeapon;
Set this class the change the default weapon (the one the player starts off with).
This variable is actually used in the MutatedDefaultWeapon() function set, and
is available to reduce that whole process down to a single variable. This variable
is how the Arena mutators work their magic.

Functions

-----------------

event PreBeginPlay();

This function is called just before the game begins. Because of the way mutators

are set up, this function can be called twice, so if you have any important things

in here that should've be done twice, you should create a boolean variable like so:

        if( bInitialized ) return;
        bInitialized = true;

Popular things to do in this function are set up variables and register this mutator

for different things (such as HUD mutators or damage mutators).

        EXAMPLE

-------

    event PreBeginPlay() {
        if (bInitialized) return;
        bInitialized = True;

        numLives = 3;		// initialize some variables
        RegisterHUDMutator();// Set self to receive PostRender() calls

        if( bHUDMutator )	// if RegisterHUDMutator() worked, bHUDMutator is true
        {
            log("Ok, I get PostRender() calls.");
        }
    }

function PostBeginPlay();

This function is not actually part of the mutator, but is instead inherited from the

Actor class. It is called after PreBeginPlay(). It is actually very similar to

PreBeginPlay(), except that it is called after certain aspects of the game have

been initiallized. Use this function to set up variables (just like PreBeginPlay),

especially if you have variables that need to be set after the game is initialized

(like in the example below).

EXAMPLE (from Botpack.DMMutator.uc)

-----------------------------------

    function PostBeginPlay()
    {
        MyGame = DeathMatchPlus(Level.Game);
        Super.PostBeginPlay();
    }

simulated event PostRender( canvas Canvas );

This function allows you to draw on the HUD. Use the Canvas passed to draw anything

you want on the HUD. This will draw directly on top of the existing HUD, which

allows your mutator to affect all HUDs with the same call. This function reduces

the need to actually create a new HUD. This function will only be called if you

first call RegisterHUDMutator() in the PreBeginPlay() function and bHUDMutator is

true. See the canvas class for drawing functions.

EXAMPLE (From RelicHUDMutator.uc, simplified for example purposes)

------------------------------------------------------------------

    simulated function PostRender(canvas C) {
        local float Scale;

        if ( MyRelic != None )	//myRelic is a mutator global variable
        {
            Scale = ChallengeHUD(PlayerOwner.MyHUD).Scale;
            C.DrawColor = ChallengeHUD(PlayerOwner.MyHUD).HUDColor;
            C.SetPos(C.ClipX - 64 * Scale, C.ClipY - 192 * Scale);
            C.DrawIcon(MyRelic.Icon, Scale);
        }
    }

function ModifyPlayer(Pawn Other);

This function is called every time a player begins a new life. Use this function to

change aspects of the player. For instance, you can reset a player's fatness, or

make him start out really skinny. If you want to affect a player when they die/kill

someone, use ScoreKill() instead.

EXAMPLE

-------

    function ModifyPlayer(Pawn Other)
    {
        Other.fatness = fatness;		// change player attributes

        Super.ModifyPlayer(Other);	// Be nice, call Super.ModifyPlayer()
    }

function ScoreKill(Pawn Killer, Pawn Other);

This function is called whenever someone dies (the Pawn Other). Killer is the

Pawn which killed Other. If Killer == none, or Killer == Other, then it was

a suicde of some sort. You can use this function to make things happen when

one player kills another (ie they get fatter). If you want to affect a player when

they first start out each life, use ModifyPlayer() instead.

EXAMPLE (from Botpack.FatBoy.uc, simplified for example)

--------------------------------------------------------

    function ScoreKill(Pawn Killer, Pawn Other)
    {
        if ((Killer != Other) && (Other != None) && (Killer != None))
        {
            if (Killer.Fatness >= 240)	// When someone is killed, their killer
                Killer.Fatness = 255;	// slowly gets fatter.
            else
                Killer.Fatness += 10;
        }

        Super.ScoreKill(Killer, Other);	// Be nice, call Super.ScoreKill()
    }

function Class MutatedDefaultWeapon();

You do not need to play with this function. Just set the variable DefaultWeapon.

function Class MyDefaultWeapon();

You do not need to play with this function. It is used internally.

function AddMutator(Mutator M);

You do not need to play with this function. It is used internally. The Arena mutators,

do override this to make sure that no other arena mutators are added to the mutator

list. The following snippet is provided if you are planning something similar.

EXAMPLE (From Botpack.Arena.uc)

-------------------------------

    function AddMutator(Mutator M)
    {
        if ( M.IsA('Arena') )
        {
            log(M$" not allowed (already have an Arena mutator)");
            return; //only allow one arena mutator
        }
        Super.AddMutator(M);
    }

function bool ReplaceWith(actor Other, string aClassName);

This function allows you to replace an actor of one class, with an actor of

another class. Call this from CheckReplacement(). You don't need to override

this function.

function bool AlwaysKeep(Actor Other);

This function is called with every Actor added to the game, including lights and

ZoneInfos and weird stuff like that. If you return a true from this function, that

actor will always be kept, even if other mutators want to get rid of it. This

partly allows you to insist on certain actors being available. If you return false,

that just means that you don't NEED the actor and don't care what happens to it. The

actor may be added, or some other mutator may get rid of it.

EXAMPLE

-------

    function bool AlwaysKeep(Actor Other) {
        if(Other.IsA('FlakAmmo'))	// Always keep Flak Ammo. Other mutators
            return true;		// cannot replace or remove Flak Ammo now.

        return Super.AlwaysKeep(Other);// Play nicely, call the super.AlwaysKeep()
    }

function bool IsRelevant(Actor Other, out byte bSuperRelevant);

This function calls CheckReplacement(). You don't need to modify this function.

function bool CheckReplacement(Actor Other, out byte bSuperRelevant);

This function allows you to decide which items get added to the game. Each actor

added to the game gets pass to this function, and you can decide whether you

want to keep it (return true), not keep it (return false), or replace it with

another class althogether (call ReplaceWith(Other, 'class'), then return false).

Remember, when you replace something, that new object gets passed to this function

too. So do have circular replacements (A replaces B, B replaces A). Also, watch

out for subclasses (see example). By setting bSuperRelevant to true, the actor

will be kept no matter what. You can use AlwaysKeep() to make sure an actor won't

be removed/replaced by other mutators.

EXAMPLE

-------

    function bool CheckReplacement(Actor Other, out byte bSuperRelevant) {
        if ( Other.IsA('WarHeadLauncher') )
            return false;				  // Fine

        if ( Other.IsA('Weapon') ) {
            ReplaceWith(Other, "ChainSaw");  // Bad - Chainsaw is subclass of Weapon
            return false;
        }

        if ( Other.IsA('Weapon') && !Other.IsA('ChainSaw') ) {
            ReplaceWith(Other,"ChainSaw");  // Good - affects all weapons but Chainsaw
            return false;
        }

        return true;
    }

function Mutate(string MutateString, PlayerPawn Sender);

This command allows you to create console commands. Whenever a player types in the

console, "mutate" all the current mutators get that string. You can decide

what you want to do with that. For instance, a player could type "mutate drop

armor" and your mutator could do something about it. Players can bind keys to

console commands, so you can use this function to add new control keys to your

mutator. It can also be used to configure your mutator in the game.

EXAMPLE

-------

    function Mutate(string MutateString, PlayerPawn Sender)
    {
        if( MutateString~="GetFat")	// Player typed "mutate GetFat" at console.
        {
            Sender.fatness = 255;
        }

        Super.Mutate(MutateString,Sender); // Be nice
    }

function MutatorTakeDamage( out int ActualDamage, Pawn Victim,
       Pawn InstigatedBy, out Vector HitLocation, out Vector Momentum,
       name DamageType);

This function sure has a lot of parameters! It is called whenever any pawn receives

any damage from any source. I do not have a lot of experience in this function, but

I would assume this would be where "Head Shots" or immunity to Lava Damage would

come in.

        EXAMPLE (from the Vampire Mutator in the UT Mod Doc at unreal.epicgames.com)

----------------------------------------------------------------------------

    function MutatorTakeDamage( out int ActualDamage, Pawn Victim,
                                Pawn InstigatedBy, out Vector HitLocation,
                                out Vector Momentum, name DamageType)
    {
        if (InstigatedBy.IsA('Bot') || InstigatedBy.IsA('PlayerPawn'))
        {
            InstigatedBy.Health += ActualDamage;
            if (InstigatedBy.Health > 199)
            InstigatedBy.Health = 199;
        }

        Super.MutatorTakeDamage(ActualDamge, Victim, InstigatedBy,
            HitLocation, Momentum, DamageType);
    }

simulated function RegisterHUDMutator();

Thus function registers this mutator with the game so that it can start receiving

PostRender() function calls. bHUDMutator will be set to true if this function

succeeds. Don't override this one.


Mutator Tutorial

Squidis Mutator Tutorial

Section 1: What is a Mutator
Section 2: What is the Purpose of this Tutorial
Section 3: The Design Phase
Section 4: Configuring Your Mutator
Section 5: Mutators Don't Have to Player Nice, but they should...
Section 6: The Mod Menu

Appendix - The Mutator Class

1) What is a Mutator?

Mutators are special classes which modify the game being played in some way. Normally, mutators are single minded in their goals, such as just making the players fat, or reducing the gravity. Mutators also have another sellling point. They can be linked together, provided they are properly written. This allows you to more fully customize your gaming experience. For instance, it allows you to be fat AND have low gravity. There is a limit to a mutator's ability to change things around, but there are still lots of really cool things you can do with it.

2) What is the Purpose of this Tutorial?

I've seen a lot a people attempt to write mutators, and I've seen a lot of people do some things which can cause problems. The purpose of this tutorial is to explain some features which may be overlooked, as well as provide a nice little list of Do's and Dont's for the aspiring mutator developer. Don't just think of this document as a tutorial...think of it as a style guide.

What this tutorial won't do, unfortunately, is tell you how to use UnrealEd to make classes. The focus of this tutorial is mutators, and nothing but. I don't want to bog things down with extraneous information. This tutorial assumes that you can examine the code from the built-in mutators to figure out the basic outline of how a mutator works. There isn't any hand-holding in this document.

3) The Design Phase

Mutators allows coders a lot of freedom in what can be done. However, one of the most important aspects to keep in mind is that mutators should be limited in scope. If you make them do too much, they won't work well with other mutators. If you provide configuration windows and menus, then you are complicating the process too much. A mutator should be something that is added to a game to change one particular aspect.

Don't create a mutator which replaces every weapon in the game with a new one, then modifies the game so that you only have 3 lives. First, the mutator really does two things. It replaces the weapons and modifies the game. What if the player wants to just use the weapons, or just wants the 3 lives aspect? That should really be two seperate mutators. If you absolutely think the two go together, then you are better off creating a GameType and not a mutator. GameTypes can't be linked together, and therefore are more suited for coherent game playing experiences. Mutators mutate. They aren't meant to be the end experience.

Second, why replace all the guns? What if the player wants to only use one or two from the set, and keep the normal guns? What if the player wants to mix and match guns from different mutator sets? The simple answer here is to split each weapon up into its own mutator. This is similar to what Epic did with the Relic mutators. Rather than having a single Relic mutator, there is a mutator for each relic. That way, you can select which relics you want to add into the game at the mutator window. This rule can apply to anything which has several options that are either on or off. For instance, if you made a mutator which added in monsters to a deathmatch level, you could create a mutator for each monster type. This saves you from having to create an unwieldly configuration dialog.

When creating gun mutators, try to replace the gun which is most similar. The weapons in UT are fairly balanced in that the different weapons appeal to different styles of play. There isn't a whole lot of need for two sniper-esque weapons. Also, the player is guarranteed to be familiar with the default weapon set. By keeping in sync with that (sniper rifles are weapon 9, melee is weapon 1, pistols 2, etc), the player can quickly handle any new weapons you can throw at him. This also has the side effect of the player being able to decide which weapons he wants. He can take the sniper rifle from the realistic weapons pack, and the pistols from the sci fi weapons pack. He can mix and match to his hearts content.

You may want to release a whole bunch of melee weapons. For instance, you may want to release a pack with swords and maces and stuff like that. Since there is really only one melee spot, what you should do is provide two ways to get at the weapons. First, provide mutators for every weapon which replaces the default melee weapon. Second, provide a GameType or second Mutator which replaces all the weapons with those mutator weapons. By doing this, the player can decide whether he wants to choose one weapon from the bunch, or just use the bunch as provided. Remember, the point of mutators is to make the game more flexible, not less so.

Finally, if you are significantly changing the gameplay, you might be better off with a GameType. It allows you to do things that mutators don't, and it is completely apparent to the player that gameplay is different. The one problem here is that if you want to change each GameType (Deathmatch, Team, CTF, Assault, etc), you need a new gametype for each kind. In this case, you obviously aren't modifying the game at a basic level (CTF isn't going to change into Assault), so this is an area where mutators are better suited. You would also need a new GameType for each of those. If everyone released 5 gametypes for every little modification, things could get really ugly. I'll leave it up to your judgement. But if you do a GameType, please see my gameType style guide tutorial first (coming soon).

4) Configuring Your Mutator

One thing about Unreal Tournament is that it allows developers to create UWindows (the built in GUI) to allow customization of mutators and mods. You can add in a menu item on the Mod Menu which allows the player to open up this configuration. My suggestion concerning this is simply: DON'T DO IT. If you've kept your mutator simple, and followed my other suggestions, then you shouldn't need to configure anything. Mutators shouldn't be configured. It is an entirely unwieldly experience selecting a mutator and then configuring it each game.

If you've got some options, and multiple mutators or a GameType (which can be configured from custom settings and rules windows) won't cover it, then you could just not make them options. If there is a choice on a subject like how many lives you get, there are several things you can do. You can provide several mutators (3 lives, 5 lives, 9 lives), or you could just hardcode what you think is the best option (5 lives?). If they player never realizes he has a choice, he won't miss not having one.

Say you have a mutator which allows you to change certain attributes of the player. You can select any fatness number you want, and drawscale number, and things like that. Being able to type in any number may seem really powerful, but it is just making things harder for the player. Think about it. What kind of fatness will the player try. He will try skinny, not so skinny, really fat, and pretty fat. You don't need to allow the player to select a fatness of 100.45. Same with scale. The player would want to play at half size, and probably at slightly larger than normal (double size is too large).

Ultimately, the plan is that mutator space is cheap. It takes two seconds to search a list and select a mutator. It takes considerably longer to open a dialog and configure it, especially when you have numbers to type in. It is regrettable that Epic didn't allow Mutator lists like it has Map Lists. That would be a good project for someone to look into.

5) Mutators Don't Have to Play Nice, but they should...

In some functions, you need to make sure you call the parent mutator's function. Some of these just call the next mutator in the list, but even that is important. If you fail to call the next mutator, then it won't work properly. People will think it is a flaw in the other mutator when, in fact, it is your mutator with the flaw. Try to work with other mutators when at all possible. You'll be glad you did. Remember, if a mutator isn't nice, you never know where it will be in the mutator list. It could be first, or it could be last. All this means is that some other mutator might have removed items you need long before the flow even gets to you.

Some mutators don't play nice. For instance, the Arena mutator remove all the weapons in the game and give the players a single type. This can lead to some incompatibilies with other mutators. For instance, try running InstaGib with Guns Akimbo mutator, and bad stuff happens. The thing about Arena mutators is that they do something really simple and to the point. However, this can affect other mutators. I suggest that if your mutator does something that can cause problems, you put it in the readme file. Before you release your mutator, test it will all the mutator that come with Unreal Tournament and test for compatibility issues. If you are feeling really lucky, test it with popular 3rd party mutators too. It never hurts to be too cautious.

6) The Mod Menu

If you absolutely feel the need to put a menu item into the mod menu, there are some style tips that I suggest. First, don't do it. The larger the menu gets, the less effective it becomes. By putting in a menu item, you are potentially making the player's life harder. Mutators should be so simple that they don't need menu items. If every mutator released had some configurable options, there would be hundreds of items on the mod menu! Hundreds! I know UWindows is a neat thing, and using it makes your mod look more professional, but ultimately, if you don't need it, don't put it in. Even mod authors who create new game types can put configurable options in the game settings and rules tabs in the game creation dialog.

Don't take up more than one mod menu item. It should go without saying, but don't take up more space than you need. If you have several configurable options, it would be better to have a single window with tabbed pages for each option set. If you want, you can even create a window which will open and allow you to have your own menu bar. The window could even display a nice logo or something. Don't think your mutator is more important than anyone else's.

For your one menu item, name it something short and to the point. If your mutator/mod is called "Terminator", call the menu item "Terminator". Don't bother putting things in the menu title which confuses it, like "Terminator Options" or "Configure Terminator Mutator". Just the single word is more than enough to convey what mod/mutator that menu pertains too. Oh, and don't use abbreviations in the name, if at all possible. I've downloaded mutators that had one name, and their mod menu title was something completely different. As it is, I've got mod menu items I have no idea where they came from or what they do. Avoid this.

Appendix: The mutator class in detail


UWindows Tutorial

What is UWindows?

Probably the first thing about Unreal Tournament you'll notice is how much spiffier the interface is. Rather than having the Wolfenstein 3D throwback menu system, UT has implemented its own small Graphical User Interface (GUI). It has windows, menus, a mouse pointer, scrollbars, and a lot of other things which other GUIs have (such as Windows). GUI interfaces are famous for making information easier to convey, and harder to program.

Luckily, UT's interface isn't really all that hard to program. If you understand some basic object orientated principles, you shouldn't have much trouble with it. If you've programmed for Windows, Java, or the Macintosh, you'll find that UT's interface is much more simple and easier to use.

UWindows may or may not be the official title of the GUI interface. The core classes all have names with the prefix UWindow, like UWindowButton or UWindowTabControlLeft. For obvious reasons, I call the interface UWindows.

How does UWindows work?

UWindows makes up the core engine of the graphics interface. It does not include any game specific classes. This allows mod makers and liscencees to make their own games with the Unreal engine without having all that extra game specific code. UT's interface exists as a layer or two above the UWindows core. Right above UWindows is the UMenu interface. It provides the basic interface with the help system, menu bar, and configuration dialogs. Built on top of UMenu is UTMenu, which is the specific classes used in Unreal Tournament.

When working with UWindows, you really shouldn't find much need to mess around with the UMenu and UTMenu layers unless you are trying to specifically change a feature of Unreal Tournament. Working with classes outside of the standard UWindows core group could mean compatibility problems with other game engines. Creating a mutator configuration window could actually work between Unreal Tournament, Wheel of Time, and even Nerf Blast Arena if you never stray past the standard classes.

It all begins with UWindowBase?

The entire class tree for UWindows, UMenu, and UTMenu all start with a single node: UWindowBase. All classes in the UWindows system stem from this single point, and they all inherit what is in it. As such, UWindowBase doesn't really have a whole bunch of code. It provides several constants and enumerations that are used amonst the bunch.

After UWindowBase, the class tree splits three ways. Probably the least important path of the three is UWindowLookAndFeel. It provided the hooks for building in the look and feel of the application. Maybe you've noticed in UT, you can change your Look and Feel between Gold, Ice, and Metal? Well, each of those Look and Feels are objects under this class. They define how buttons are drawn, and what a menu looks like, and so on. Nerf Blast Arena even has its own Look and Feel. However, the provided L&Fs should be more than enough to satisfy most ideas.

The second branch past UWindowBase is the UWindowList tree. None of the classes under UWindowList are graphical objects. UWindowList provides a basic linked list functionality for its children classes. Most of the child classes are specific lists used in the GUI, such as a list of menu items, or the list of strings in a combo box. There really isn't a whole lot to monkey around with in this section, although you do need to subclass at least one thing here.

The third and final branch of the tree is UWindowWindow. While it says window, it really isn't. In this case, the window it is refering to is a rectangular graphic. This could be a window window, but this could also be a menu, or a button. All objects under UWindowWindow are visible objects that can be messed with by either the mouse or the keyboard. To distinguish between a UWindowWindow and a window with a title bar that can be moved around, I shall refer to the latter as a Framed Window.

The really cool thing about everything descending from UWindowWindow is that anything under this class can have anything else in this class inside it. You can have Framed Windows with menu bars, and menu bars with buttons, and even buttons that pop up menus. By careful construction of the class tree, Epic hsa made it very functional and very easy to use.

So everything is a window?

All visible graphical objects are descended from UWindowWindow. They all share the same properties and values defined in this class. Easily the most important of these are four variables: WinLeft, WinTop, WinWidth, and WinHeight. These variables form the rectangle that the window occupies. There are a few boolean variables of note, such as bAlwaysOnTop, bAlwaysBehind, and bWindowVisible.

There are several functions in UWindowWindow which don't do anything, but are worth pointing out. Functions like BeginPlay(), BeforeCreate(), Created(), AfterCreate(), Activated(), and Resized() allow their functionallity to be filled out by the children classes. You might override the Created() function of a window to add controls to it. Just be sure that when you override a function to call the parent function too (ie Super.Created()).

How do I start?

This tutorial assumes you are already a little familiar with UScript, and have a mutator or two done. The provided sample code assumes a mutator called sqFatMutator with two variables: fatness and bUseTwoGuns.

The first thing you need is a starting place. UT needs to know when and how to create a window for you. Luckily, UT makes this easy by providing a built in starting place: the MOD menu. Normally, this menu is invisible, but shows up when you add your first item to it. You create your own spot on the menu by subclassing UMenuModMenuItem (from the UWindowList tree). Notice that it is a UMenu class and not a UWindow one. The UMenuModMenuItem has only two functions: Setup() and Execute(). Here is the code for a sample mod menu item (remember to change the class names and what-not to your classnames first).

One the class is completed and compiled, add a line similar to the following to your .int file:

[Public]

Object=(Name=SquidiMods.sqFatModMenuItem,Class=Class, MetaClass=UMenu.UMenuModMenuItem)
------------------------------------------------------------------

class sqFatModMenuItem expands UMenuModMenuItem;

function Setup()
 {

//The MenuCaption variable is used to store the menu item's name on
 // the menu. Unfortunately, the menu item is created before Setup()
 // is called, and thus uses the default property. Still, this is
 // provided as a reference.
 MenuCaption = "FatMutator Config";

//MenuHelp is simply the string written in the status bar at the bottom
 // of the screen when the mouse hovers over this menu item. Luckily
 // for us, setting the help caption here DOES work.
 MenuHelp = "Sets up the FatMutator";

}

function Execute()
 {

//Create a window using the following function:
 // CreateWindow( class, top, left, width, height )

//The window I will create will automatically resize itself to
 // the right proportions (I'll show you how when we get to the
 // Framed Window part), so it doesn't matter what the top, left,
 // width or height variables are. Just the class portion matters.

MenuItem.Owner.Root.CreateWindow(class'sqFatConfigWindow',
 10,10,10,10);

}
 ------------------------------------------------------------------

It didn't compile!

When UnrealEd tries to compile this code, it'll point out that you haven't
written the sqFatConfigWindow class yet. So lets do that. What we are going
to do is subclass UWindowFramedWindow to create a nifty little frame which
we drag around the screen to our heart's content.

------------------------------------------------------------------

class sqFatConfigWindow expands UWindowFramedWindow;
function BeginPlay()

{

Super.BeginPlay(); //Set the title of the Framed Window
 WindowTitle = "Configure Fat Mutator";
//The class of the content
 ClientClass = class'sqFatClientWindow';

//Make the Framed Window resizable
 bSizable = true;

}
 ------------------------------------------------------------------

Most of this code is pretty self explanatory, with the exception of the
ClientClass variable. If this variable were set to None, you'd see that
when the window was created you would just get the framed part. The insides
would show through to the background! A FramedWindow is just that, a frame.
When ClientClass is set to a valid client window class, when the window is
created, that class will be created along with it. You don't need to worry
about making both of them.

You'll find the class UWindowClientWindow just under UWindowWindow, but
that isn't the client window type we are going to use. A child class of
ClientWindow, UWindowDialogClientWindow has a few extra important functions
required to use controls. So we are going to subclass that one instead. It
also has an extra ability to suggest a desired width and height for the
content. Just subclassing UWindowDialogClientWindow is enough to fill in
the empty space in the Framed Window.

Ooh. How do I add buttons and stuff?

Content is added in the form of controls. All controls are children of
UWindowDialogControl (which in turn is a child of UWindowWindow). So all
controls are also windows. There are dozens of controls to choose from. Some
of the controls share functionality (for instance UWindowCheckbox and
UWindowSmallButton are both children of UWindowButton), but most have
individual options to tweak. Controls are created, and added to your client
window via the UWindowDialogClientWindow.CreateControl() function that
you'll have inherited. It has the same parameters as the CreateWindow()
function. Here is a somewhat modified version of my sample client window
class:

-----------------------------------------------------------------

class sqFatClientWindow expands UWindowDialogClientWindow;
var UWindowCheckBox checkbox;

var UWindowHSliderControl slider;
// called after object has been created...add content

function Created()

{

Super.Created(); //Add checkbox via the CreateControl() function.
 checkbox = UWindowCheckBox(
 CreateControl(class'UWindowCheckBox', 10, 10, 150, 1));
 checkbox.SetText("Two Guns");
 checkbox.bChecked = true;

//create slider in same fashion
 slider = UWindowHSliderControl(
 CreateControl(class'UWindowHSliderControl', 10, 30, 150, 1));
 slider.SetText("Fatness");
 slider.SetRange(1,255,5);
 slider.SetValue(128,true);

} //when a control changes, Notify is called with the changed control
 // and the message sent.
 function Notify(UWindowDialogControl C, byte E)
 {

switch(E)
 {
 case DE_Change: // the message sent by sliders and checkboxes

switch(C)
 {
 case slider:
 //get slider value
 break;
 case checkbox:
 //get checkbox info
 break;
 }

break;
 }

}
 ------------------------------------------------------------------

The Notify() is how you know when one of your controls has changed in
value. This allows you to update the variables the controls were supposed
to reflect. The message sent in this case is the DE_Change one, which is
the message most often used. You can also use Notify() to update the text
on the controls. For instance, the fatness control can change from skinniness
to fatness depending where the slider is.

Great! That's just about it. How do I interact with my mutator?

To make the config dialog more useful, those levers and buttons actually
need to affect something in your mutator. This is accomplished by setting
the default values. This can easily be accessed via a line similar to this:

class'SquidiMods.sqFatMutator'.default.fatness = slider.GetValue();
class'SquidiMods.sqFatMutator'.static.StaticSaveConfig();

The final version of my client window sample follows:

-----------------------------------------------------------------

class sqFatClientWindow expands UWindowDialogClientWindow;
var UWindowCheckBox checkbox;

var UWindowHSliderControl slider;
// called after object has been created...add content

function Created()

{

Super.Created(); //Add checkbox via the CreateControl() function.
 checkbox = UWindowCheckBox(
 CreateControl(class'UWindowCheckBox', 10, 10, 150, 1));
 checkbox.SetText("Two Guns");
 checkbox.bChecked =
 class'SquidiMods.sqFatMutator'.default.bUseTwoGuns;

//create slider in same fashion
 slider = UWindowHSliderControl(
 CreateControl(class'UWindowHSliderControl', 10, 30, 150, 1));
 slider.SetText("Fatness");
 slider.SetRange(1,255,5);
 slider.SetValue(
 class'SquidiMods.sqFatMutator'.default.fatness, true);

} //when a control changes, Notify is called with the changed control
 function Notify(UWindowDialogControl C, byte E)
 {

local int sval;

switch(E)
 {

case DE_Change: // the message sent by sliders and checkboxes

switch(C)
 { case slider:
 sval = slider.GetValue();
 class'SquidiMods.sqFatMutator'.default.fatness = sval;
 class'SquidiMods.sqFatMutator'.static.StaticSaveConfig();

if( sval > 0 ) slider.SetText("Fatness [Skinny]");
 if( sval > 50 ) slider.SetText("Fatness [Slim]");
 if( sval == 128) slider.SetText("Fatness [Normal]");
 if( sval > 175 ) slider.SetText("Fatness [Fat]");
 if( sval > 200 ) slider.SetText("Fatness [Fatboy]");
 break; case checkbox:
 class'SquidiMods.sqFatMutator'.default.bUseTwoGuns
 = SomeCheck.bChecked;
 class'SquidiMods.sqFatMutator'.static.StaticSaveConfig();
 break;
 }

break;

}

}
 -----------------------------------------------------------------

Read Part Two of this tutorial: Advanced UWindows Techniques


UWindows Tutorial 2

UWindows Tutorial Part 2

Part 1: Before We Begin
Part 2: Creating and Using Menus
Part 3: Tabbed Pages
Part 4: Scrolling Client Areas

Part 1: Before We Begin

This tutorial assumes you are already familiar with the basics of programming the UWindows system. This includes making windows and client windows, adding controls to windows, adding a spot on the modmenu, and generally understanding the terminology. When I talk about ClientWindows and FramedWindows, I am going to assume that you know the difference between them. As such, I will not walk you through the process of doing these things. Please see my introductory tutorial for that type of help.

All of my class names begin with 'sq' (for Squidi), and then an uppercase abbreviation of what that particular item is. ClientWindows are CW, Framed Windows are FW, Menu Bars are MB, Menus are M, and so on. Then is the mod type (in this case "Tutorial"). After that, if it is necessary, is a description of the object. sqFWTutorial and sqCWTutorial are sufficient enough to distinguish a difference. However, individual menus might be called sqMTutorialGame and sqMTutorialHelp.

Part 2: Creating and Using Menus

To use menus in your configuartion windows, you need a way to get to the menu. This can be accomplished through a MenuBar, or through using Right Clicks to bring up a pop up menu. MenuBars are a little easier follow, so we'll start there. To create a Menu (and MenuBar), you must subclass the appropriate object (UWindowMenuBar and UWindowPulldownMenu). Since both MenuBars and Menus are descendents from UWindowDialogControl, they can both exist inside framed windows, and are created using the CreateControl() function.

In the following examples, I haven't implemented the tooltips helpbar that the main menu bar makes. It makes things a little more complicated. If you want to add in this help functionality, checkout UMenuGameMenu and the likes. Also, I won't go into Right Click menus at this time, as I'm unsure how Mac users do the right click. I don't want to promote an activity that I'm not sure everyone can participate in.

//====================================================================

// sqMBTutorial.

//====================================================================

class sqMBTutorial expands UWindowMenuBar;
var UWindowPulldownMenu Game, Help;

var UWindowMenuBarItem GameItem, HelpItem;
function Created()

{

Super.Created(); bAlwaysOnTop = False; GameItem = AddItem("Game");
 Game = GameItem.CreateMenu(class'sqPMTutorialGame');

// For this menu, we are using the built in HelpMenu
 HelpItem = AddItem("Help");
 Help = HelpItem.CreateMenu(class'UMenuHelpMenu'); Spacing = 12;

}
/**
 ** Adding in the following code will make the menuBar drawn in the
 ** current look and feel, as opposed to a generic gray one
 **
 ** function DrawMenuBar(Canvas C)
 ** {
 ** LookAndFeel.Menu_DrawMenuBar(Self, C);
 ** }
 **
 **
 **/
//====================================================================
 // sqPMTutorialGame.
 //====================================================================
 class sqPMTutorialGame expands UWindowPulldownMenu;
var UWindowPulldownMenuItem NewGame, Load, Save, GameOptions, Quit;
function Created()
 {

Super.Created(); // Add menu items.
 NewGame = AddMenuItem("New Game", None);
 Load = AddMenuItem("Load", None);
 Save = AddMenuItem("Save", None);
 AddMenuItem("-", None);
 Quit = AddMenuItem("Quit", None);

}
function ExecuteItem(UWindowPulldownMenuItem I)
 {

switch(I)
 { case NewGame: // new game menu item was selected

break;

case Load: // Load menu item was selected

break;

case Save: // Save Menu Item was selected

break;

case Quit: // Quit menu item was selected

break;

} Super.ExecuteItem(I);

}

Add the MenuBar to your window with the following code (in the clientwindow's Created() function):

MenuBar = sqMBTutorial(CreateWindow(class'sqMBTutorial', 0, 0, WinWidth, 16));

And that's about it. You may want to put some code in the client window's Resized() function to change the width of the menuBar when the window changes sizes. Otherwise, the user may make the window larger than the menuBar, and you'll see empty space. Another thing of note is that you don't need to add a menuBar to the top of a window. You can put it anywhere. Just remember that the pulldown menus will drop below the menuBar no matter where the location is.

Part 3: Tabbed Pages

An example of Tabbed Pages can be seen in the preferences dialog. The window has several tabs at the top of the window which will select between the different pages of configurable options. Making a TabbedPage is incredibly easy. You just need to create a control of type UWindowPageControl, and then add the different pages to it. Each page is just a client window of type UWindowPageWindow. Since UWindowPageWindow is descended from UWindowDialogClientWindow, you create them in the same fashion as you would a normal client window. In fact, if you aren't really sure whether or not your client window will ever be used in a tabbed page, you can go ahead and make it a subclass of UWindowPageWindow anyway. The change is transparent to UWindows, and saves you from having to change parent classes if you decide later on to put it under a tab.

To create a tab control, just do the following in your client window's Created() function:

Pages = UWindowPageControl( CreateWindow(class'UWindowPageControl', 0, 0, WinWidth, WinHeight));

To add a page to the tab bar, just use the following code, where XXX is the class name of the Page Window you want to add. And that's it. The most important thing to remember is to subclass UWindowPageWindow for your client window needs.

Pages.AddPage("Test", class'XXX');

Part 4: Scrolling Client Areas

Maybe you've noticed that when you resize windows, the controls and content don't change. They are obscured by the edges of the window when it gets too small. One way to change this is to resize each of the controls when the window changes in size. My client window has the following code to make sure the menu bar and tabbed controls stay with proportion to the window's size. The function Resized() is called whenever the client area changes size.

function Resized()

{

Super.Resized(); MenuBar.WinLeft = 0;
 MenuBar.WinTop = 0;
 MenuBar.WinWidth = WinWidth;
 MenuBar.WinHeight = 16;
 Pages.WinTop = 20;
 Pages.WinLeft = 10;
 Pages.WinWidth = WinWidth - 20;
 Pages.WinHeight = WinHeight - 30;

}

This works great because the menu bar and tab area always have a size relative to the window. But in cases where you have controls and other client windows, you can't always change their size small enough. The solution to this is to provide a scrollable area. The class UWindowScrollingDialogClient (which is a Page Window) provides scrollbars which allows its own client area to remain the same size and be scrolled around in.

They are really easy to use. Just like a framed window, they have a client class variable which will create the specified client area. This time the client window doesn't need to be a PageWindow. Here is some sample code (lifted straight out of UMenuHUDConfigScrollingClient)

class UMenuHUDConfigScrollClient extends UWindowScrollingDialogClient;

function Created()

{

ClientClass = Class<UMenuPageWindow>(DynamicLoadObject( GetPlayerOwner().MyHUD.HUDConfigWindowType, class'Class')); Super.Created();

}

The scrolling client exists as an invisible layer between the client area, and the container in which the client area exists. Most of UT's dialogs use scrolling clients for the internal client areas. Then if the area is too large, or the user sets big fonts, the user can still get to every control. You should really use scrolling clients whenever you get the chance, as they add functionality which either is invisible to the user, or makes his life a lot easier. It does, however, add one more class to your user interface for each client area which uses it.


Switches and Cases

by Postal v1

I remember when a multi-mode gun was something special. Now there a dime a dozen. I have noticed many people are going the way of making a variable called int(i.e. var int mode) then using if and else if questions (i.e. if (mode == 1) etc then else if (mode == 2) and so forth) which is perfectly good, but Switch is so much better. Switch allows you to select one of a set of options, then use that. Well I shall get to the code so you can see how it works, instead my having my babble on incoherently.

//

Var() Enum EMode {M_1,M_2,M_3,M_4} Mode;

ok this goes up in with the variables

var[use () if you want to be able to select which mode it starts off in, with default props]

Enum E[mode series name, I use mode, but you can use what ever you want ]

{

M_[a mode name]

,

M_[another mode name]

}

[mode series name]

;

So you may have something like this for weapon :

Var() Enum EMode {M_1,M_2,M_3,M_4} Mode;

or something like this for a bot

Var Enum EMood {M_Happy,M_Sad,M_Angry,M_Berserk} Mood;

but for this tutorial, I shall use:

Var() Enum EMode {M_MachineGun,M_RocketLauncher,M_FlameThrower} Mode;

copied straight from a multi mode grenade launcher

//

Now the switch code, the code is basically like what you will be using. This is set up using the same names in my example.

switch (Mode)

{

case M_MachineGun:

break;

case M_RocketLauncher:

break;

case M_FlameThrower:

break;

}

Each case is a option, and the break is where it ends

now for something practical, here is sort of like what you may use in a weapon.

function Fire( float Value )

{

switch (Mode)

{

case M_MachineGun:

Spawn(class'bullet');

break;

case M_RocketLauncher:

Spawn(class'rocket');

break;

case M_FlameThrower:

Spawn(class'flameburst');

break;

}

}

I hope you get the idea.

//

Now you probably are wondering how to switch between cases, well all you need is:

Mode= M_RocketLauncher;

[Mode series name] = M_[The new Mode name];

so if for example you want to have altfire switch modes you could have code like:

function AltFire( float Value )

{

ChooseMode();

}

Function ChooseMode()

{

switch (Mode)

{

case M_1:

Mode= M_RocketLauncher;

PlayerPawn(Owner).ClientMessage("Mode 2",'Event',true);

break;

case M_2:

Mode= M_FlameThrower;

PlayerPawn(Owner).ClientMessage("Mode 3",'Event',true);

break;

case M_3:

Mode= M_MachineGun;

PlayerPawn(Owner).ClientMessage("Mode 1",'Event',true);

break;

}

GoToState('AltFiring');//A place to play animation/sounds and to kill time

}

Well that is all, now should have everything you need to use switches, and if you still do not understand, mess around with the code in a weapon, you should be able to get the hang of it quickly.

//

Thanks:

Kobain for making me do this

Kangus for help with spelling/ suggestions/ and having me change a good bit of it


Unreal Script

by Windex

windex@planetunreal.com

Introduction

So, I'm guessing the first question floating through your mind would be, What the hell is UnrealScript? Well, UnrealScript is the mini programming language that Unreal mods are written in. If you've had experience coding with C++ or JavaScript, you'll probably catch on quickly. UnrealScript syntax is almost identical to JavaScript, so JavaScript books and tutorials are good resources for learning your UnrealScript vocabulary.

If you've never written a line of code in your life, though, don't give up. Everyone has to start somewhere, and UnrealScript is as good a place as any. I've tried to make this tutorial as simple and basic as possible, so it can be understood by just about anyone. Like anything else, UnrealScript takes practice to become good at, but that doesn't mean it can't be fun along the way.

L e t ' s g e t s t a r t e d . . .

There are two methods for writing UnrealScript. The first, and simplest, is to use UnrealEd, which comes fully featured with everything you'll need to get started in UScript. The second method involves writing code in plain text .uc files, and compiling them using Unreal -make. This is usually the preferred method for most experienced UScripters, because it gets rid of complications and bugginess caused by UnrealEd. It also allows for easier mixing and matching of new models. Information on how to use this method is contained in the Using Unreal -make tutorial. If you're just starting out, though, I would have to recommend that you stick to UnrealEd for now. As a result, this is the method I'll talk about most during this tutorial. If you've never run UnrealEd before, you'll need to grab a couple of bug fixes to make sure it works properly. Download and install the Visual Basic 5.0 Runtime, and the RichText Control Update, and you should be set.

Alright. It's time to start your career in UnrealScript. Open up UnrealEd, and take a look around. The first thing you'll probably notice are the grided viewports in the center. These are meant for level design and you won't be using them for writing UnrealScript. Now take a look on the right. This is the browser window. By default, it displays textures for level design, but this isn't what you want. Click on the "Browse" pull-down menu, and select "Classes". This will bring up the class tree.

W h a t i n t a r n a t i o n i s a c l a s s ?

You may have heard the term "Object Oriented Programming" before. C++, Java, JavaScript, and UnrealScript are all object-oriented languages. OOP is a fairly new concept, and it's one that can make the task of programming quite a bit easier. Especially when you're writing code for an FPS, where it's easy to think of things as actual "objects" in the game. Everything you see and interact with in Unreal (as well as quite a few things you can't see) is an object. Your eightball gun is an object. The rockets and grenades it fires are objects. The unfortunate krall at the other end of these rockets and grenades is an object. All of these things are controlled by written code, which is contained in a class. So, there's the answer to that question. A class is simply a collection of code which is used to control some object in the game. Each object has its own class.

A popular analogy is to think of a class as a mold that is used to create objects in the game. You might have more than one skaarj in a game at the same time, but that doesn't mean that these skaarj are identical. One of them could be patrolling peacefully at its post, and the other might be fighting for its life against a blood-crazed player with an attitude and a big gun. They are both created from the same class, or "mold", but they are controlled separately.

In case you're new to 3D game development, there's something I should probably explain at this point. I've said an object is something in the game that can (usually) be seen and interacted with. What you "see" however is not dictated by the code you write for it. What you see is a 3D model which is created in a separate program entirely, such as 3D Studio Max or Lightwave. The code you write controls what the object does. A model without code will just sit there and do nothing in the game. Code makes your eightball fire when you click the mouse button, makes the rocket appear in front of you, and makes it speed off to explode between your enemy's eyes.

M o v i n g O n

Now that you have some concept of what a class is, it's time to look at them in a little more depth. Go back to to the class browser in UnrealEd, and look it over a bit. Classes in Unreal are arranged in a hierarchy, with the "Actor" class at the top. Actually, Actor is not the highest class, but it's as high as you'll need to go for now. Just so you know, "Object" is at the true top of the tree, and it can be displayed in the class browser by deselecting the Only show actor classes box.

The idea behind having the classes arranged in a hierarchy is that each class will inherit code from the classes above it. Code that will be used for every class in the game is put in the top-most class, so it will be inherited by all the classes below it. This is very useful, since it means that you don't have to re-invent the wheel for each new class you create. If you want to create a new weapon, for instance, you can simply expand upon the existing Unreal weapon class, and add only the functionality that is specific to your weapon, instead of unnecessarily re-writing code that is already written in the base weapon class.

Now, click on the little minus sign by the word "Inventory" to display its child classes. After that, expand "Weapon", and look at what appears. All the Unreal weapons are child classes of Weapon, which is a child class of Inventory, which is a child class of Actor. There is quite a bit of code in Inventory and Weapon which controls the basics of how a weapon should act, but the specific code that controls how each individual weapon works is contained in that weapon's class. To get your first look at UnrealScript in all its glory, double-click on the FlakCannon class. A window with a dark blue background will appear, containing all the code for the FlakCannon. If you've written C++ or JavaScript before, you'll probably recognize quite a bit of the syntax. If you're new to programming, though, don't panic. Code may look complicated at first, but once you break it down, it's really very simple.

Code in UnealEd is color coded, as you've probably noticed already. Comments (text which is ignored by the compiler, and used to explain and document your code) are bright green, keywords are aqua blue, labels are yellow, exec commands are gray, and everything else is white. The first line of aqua blue and white when you first open the class is called the class declaration. Under this are the gray exec commands. These are used to import the models, sounds, and textures used by the class, and can be ignored for now. Scroll down till you get to some more colorful code. This code contains the variables, functions, and states of the class, and is what actually controls what the FlakCannon does.

T h e C l a s s D e c l a r a t i o n

The class declaration is a line of code in a class which states the name of the class, and its parent class. The class declaration for the FlakCannon looks like this:

FlakCannon Class Declaration

    class FlakCannon expands Weapon;

Not too difficult, is it? All it consists of is the word "class", followed by the name of the class, then the word "expands" followed by the name of the parent class and a semicolon. The semicolon is just a way of telling the compiler that the statement is finished. Just about everything you write in UnrealScript will need a semicolon at the end, so get used to it.

Now, when writing code in UnrealEd, you won't have to worry about the class declaration much, since UnrealEd will automatically generate this line of code when you create a new class. However, if you write code in text-based .uc files outside of UnrealEd, you will need to write the class declaration manually.

I n t r o d u c i n g : V a r i a b l e s

If you've ever done any programming before, I'm sure you have a firm concept of what a variable is, and what they're used for. If this is the case, you should probably skip down to the "Types of Variables" section below. If the question What the hell is a variable? is floating around in the back of your mind (or the front of it, for that matter), though, you'll want to keep reading.

Technically speaking, a variable is a location in your computer's memory that stores a piece of information. This information can be of many different types, such as numbers or words. Variables come in handy all the time while writing code. For example, let's say you're making a new weapon, and you want it to charge up in alt-fire. To accomplish this, you could use a variable. When the player presses alt-fire, have Unreal add to this variable. Then, when the player presses fire, have Unreal fire a projectile that does a varying amount of damage according to the value that was stored in your charge variable.

Damn, I didn't do a very good job explaining that, did I? Well, hopefully you're able to grasp the concept of variables without much help from me. I've found that most people don't have much trouble with it. It's just one of those things that naturally makes sense.

T y p e s o f V a r i a b l e s

If you've done any programming in BASIC, or a similar language, you've probably become accustomed to using variables a certain way. Namely, not having to declare them. Declare them, you ask? Yes, declare them. Variables in UnrealScript, just as in C++, Java, and JavaScript, must be declared before you can use them. Basically, you have to let Unreal know that you are going to use a new variable. The basic variable declaration syntax in UnrealScript looks like this:

The Variable Declaration

    var [vartype] [varname];

Pretty straight-forward. First comes the keyword "var", then the type of variable you are declaring, and finally the name of the variable. Variables must be declared at the beginning of a class, after the class declaration and exec commands, but before any functions. There are many different types of variables, ranging from numbers, to letters and words, to "true" or "false" values. The types available in UnrealScript are as follows:

I n t e g e r

Keyword: int

An integer number value. For those of you not familiar with what an integer is, it's a whole number that can also be negative. In other words, anything without a decimal. 37 is an integer. 2 is an integer. -674 is an integer. 6.3432 is not an integer.

Integer Example

var int myInt;

myInt = 3; //Assign a value
myInt++; //Increment
myInt--; //Decrement

Note the special syntax you can use to add or subtract one from an integer. Saying "myInt++;" does the same thing as saying "myInt = myInt + 1;", and saying "myInt--;" does the same thing as saying "myInt = myInt - 1;".

F l o a t i n g P o i n t

Keyword: float

A number value that, unlike an integer, can include decimals. 6.3432, 4534243.2, and -0.98 are all floating point numbers.

Floating Point Example

var float myFloat;

myFloat = 3.2453; //Assign a value

You cannot increment and decrement a float using the same syntax as an int. To add one to a float, you would have to say "myFloat = myFloat + 1;", not "myFloat++;". It's also important to keep in mind one other thing when working with integers and floats. Take a look at these examples:

Integers and Floats Don't Mix

var int myInt;
var float myFloat, Result;

//Example 1
myInt = 5;
myFloat = 0.5;
Result = myFloat * myInt;

//Example 2
myInt = 5;
myFloat = 2.0;
Result = myInt / myFloat;

In example one, Result will not equal 2.5. Because you are multiplying an integer by a float, you will always get an integer back. If you wanted to get 2.5 back, you would have to declare myInt as a float, not an int. The same is true for example two. Even though you are dividing 5 by 2, and assigning the result to a float, you will not get 2.5 back, because the 5 is an integer. Also, note the way I've declared the two floats in this example. You can declare multiple variables in the same statement by simply separating the different variable names with commas.

B o o l e a n V a l u e

Keyword: bool

A value which is either "true" or "false". These have not always been around, since it's possible to simply use an integer, and set it to either 0 or 1. This would give the same effect. However, it's easier to see and understand the words true and false than it is to understand a 0 or 1, so the bool was introduced.

Boolean Example

var bool bMyBool;

bMyBool = true; //Assign a value

Note that the prefix "b" is often used in boolean variable names. This is just a naming convention, though, and it's not a required.

B y t e

Keyword: byte

An integer value in the range of 0 to 255. The use of these may not be apparent at first glance. You're probably saying to yourself, Why not just use an integer? Well, I honestly can't answer that. I very rarely (if ever) use these, so I'm not extremely clear on their advantages. I can give you an example of one thing they are used for, though, and that is RGB color values, which fall in the range of 0 to 255.

Byte Example

var byte bMyByte;

bMyByte = 255; //Assign a value

Again, note the prefix "b". For some reason, Epic chose to use the same naming convention for both bytes and bools. So, be careful not to confuse the two when looking through existing scripts.

S t r i n g

Keyword: string

A string is simply a bunch of alpha-numeric characters. In other words... well, words. Strings of letters and numbers that make up words and sentences.

String Example

var string[32] String1; //Declare string
var string[32] String2;
var string[32] Result;

String1 = "Blah"; //Assign a value
String2 = "Gah";

//Combine two strings
Result = String1 $ String2;

//Find left 2 characters of String1
Result = Left(String1, 2);

//Find right 2 characters of String1
Result = Right(String1, 2);

//Find the number of characters in String1
Result = Len(String1);

//Return String1 in all caps
Result = Caps(String1);

Note that strings are declared in a special way. The number in the square brackets after the word "string" is the maximum number of characters the string can be. In this example, the maximum length of String1, String2, or Result would be 32. There are also many special operations which can be performed on strings, such as "concantations" (or combining two strings into one), finding left or right characters, or finding the length of the string.

N a m e

Keyword: name

Names are a tough one. They're hardly ever used, and understood by few. I'll do my best to explain them, though. The only application I can think of for them is in tags. If you've done any level design, you've probably used tags. They're used to associate one object with another in order to trigger certain events. Anyway, tags are simply name variables. It can be easy to confuse names with strings, but names are not strings. A string can be modified dynamically, but a name is simply a label for an object.

Name Example

var name MyName;

MyName = 'Windex'; //Assign a value

E n u m e r a t i o n

Keyword: enum

Enumerations are simply a way of defining a type of variable that can be one of a certain pre-defined set of values. Like bools, they're not absolutely necessary, since integers could be used to get the same effect. However, it's easier to see understand a set of descriptive words instead of a bunch of numbers.

Enumeration Example

//Declare a new enumeration
enum EColor;
{
    CO_Red,
    CO_Blue,
    CO_Green
};

//Declare variable of type EColor
var EColor MyColor;

//Assign a value
MyColor = CO_Blue;

Note that the "CO_" preceding each of the color values is simply a naming convention, and is not required. You can name your enumeration values anything you want.

A c t o r R e f e r e n c e

Keyword: n/a

Actor references are a special type of variable that references an actual object in the game. It will be difficult to fully grasp them at this point, but I'll give you the basics, at any rate. Later on, once I've introduced functions, I'll go into more detail about them.

Actor Reference Example

//Declare a reference to any actor
var Actor MyActor;

//Declare a reference to a pawn
var Pawn MyPawn;

//Declare a reference to a weapon
var Weapon MyWeapon;

You'll notice I didn't include any examples explaining how you assign a value to an actor reference. This is because you can only set an actor reference equal to another actor reference, or to a newly spawned actor using the Spawn() function. As I said, actor references are difficult to explain at this point, but I'll go into more detail later, once you've learned a bit more.

C l a s s R e f e r e n c e

Keyword: class

Class references, like actor references, are a special type of variable. Also like actor references, they're difficult to explain at this point. I'll do my best, though. A class reference, unlike an actor reference, doesn't reference an actual object in the world. It references a class itself, or the mold. It references the thing that creates objects, instead of the objects themselves.

Class Reference Example

//Declare a class reference
var class<Actor> MyClass;

//Assign a value
MyClass = Class'Pawn';

The word "Actor" in angle brackets after the word "class" in the declaration means that Actor is the upper limit of this variable. What this means is that MyClass cannot be set equal to anything higher than Actor in the class tree. Class references are assigned values by using the keyword Class, followed by the name of a class in single quotes.

S t r u c t

Keyword: struct

A structure is a way of defining a new type of "super-variable" that is made up of individual components. A struct is actually similar to a class, although a very simple class that can only contain variables. Structs define a new type of variable that can be declared and used just as any other variable. Take this example:

Struct Example

//Define a new struct
struct Box
{
    var float Length;
    var float Width;
    var float Height
};

//Declare a couple variables of type Box
var Box MyBox, YourBox;

//Assign values to individual components
YourBox.Length = 3.5;
YourBox.Width = 5.43;
YourBox.Height = 2.8;

//Set MyBox equal to YourBox
MyBox = YourBox;

The struct defines a new type of variable, called "Box", which has three sub-variables to it: length, width, and height. Once you define a variable of the new type, you can assign values to its individual components with the syntax "VarName.ComponentName". One very common struct in UnrealScript is the vector, which is made up of X, Y, and Z components. The techniques of working with vectors are somewhat complex, and you can learn more about them in the Vectors tutorial.

C o n d i t i o n a l s

If you've ever done any programming before, you're almost sure to be familiar with the If/Then/Else statement. They exist in UnrealScript as well, although the syntax might be slightly different than what you're used to if you program in a BASIC language. If you've never programmed before, then allow me to explain. A conditional is a way of having Unreal perform certain operations only if a certain condition is met. For instance, do one thing if a bool is true, and do something else if it's false. Conditionals are key to accomplishing all sorts of things in any programming language, and UnrealScript is no exception. The basic syntax for a conditional in UnrealScript is:

Conditional Syntax

if ([expression1] [operator] [expression2])
{
    Do some stuff here;
}
else if ([expression1] [operator] [expression2])
{
    Do more stuff here;
}
else
{
    Hey, look, more stuff;
}

First, Unreal checks to see if the first condition is true by comparing expression1 to expression2 using the operator. If that condition checks out, then the first set of commands are executed, and the conditional is finished. If the first condition isn't true, though, Unreal will check the second condition, and if it's true, it'll execute the second set of commands. If it goes through all the conditions, and none of them are true, it will execute the "else" set of commands. When writing a conditional, you don't have to have else if's and else's. They're just available should you need to be more specific with what you want Unreal to do. All you have to have when writing a conditional is the first "if" statement. There are many different operators that can be used in conditionals, as you can see in this table:

Operator | Description
== | Equal to
!= | Not equal to
< | Less than
> | Greater than
<= | Less than or equal to
>= | Greater than or equal to
~= | Approximately equal to

Not every operator will work with every variable type. For instance, you can't really say that one actor reference is "greater than" another actor reference, so the four greater than/less than operators aren't applicable to actor references. Just use common sense to determine what will work with what, and you should be just fine.

Basic Conditional

var bool bSomeBool, bSomeOtherBool;
var int SomeInt, SomeOtherInt;

if (SomeInt > 3)
{
    SomeInt is greater than 3, so do
    something;
}
else if (SomeOtherInt <= SomeInt)
{
    SomeInt is not greater than 3,
    but SomeOtherInt is less than or
    equal to SomeInt, so do something
    else;
}
else
{
    All the conditionals failed, so
    do this;
}

if (bSomeBool)
{
    bSomeBool is true, so do this;
}
else if (!bSomeOtherBool)
{
    The first conditional failed, but
    bSomeOtherBool is false, so do this
    instead;
}

Note the way I used the bools in the second conditional. Because bools can only be one of two values (true or false), they don't need to be compared using two expressions. Saying "if (bSomeBool)" is the same as saying "if (bSomeBool == true)", and saying "if (!bSomeOtherBool)" is the same as saying "if (bSomeOtherBool == false)". Now, moving on, what if you wanted to do something only if two conditions were true? Or what if you wanted to do something if only one of two different conditions were true? That's where these operators come in:

Operator | Description
&& | And
|| | Or

These are used to link conditions together in the same statement. Take a look at this example:

Conditional with && and ||

var bool bSomeBool;
var int SomeInt, SomeOtherInt;

if (SomeInt > 3 && SomeOtherInt < 3)
{
    SomeInt is greater than three,
    and SomeOtherInt is less than
    three, so do something;
}
else if (SomeOtherInt == SomeInt || !bSomeBool)
{
    The first condition failed, but
    either SomeOtherInt equals SomeInt,
    or bSomeBool is false, so do this
    instead;
}

In the first one, && links the two statements together, so the condition is only true if both statements are true. In the else if, || links the two expressions together, so the condition will be true if either of the statements is true.

O t h e r F l o w C o n t r o l D e v i c e s

In addition to "if" statements, there are other ways to control how code flows. Things such as loops and switch statements will allow you to fine-tune your code, and get the results you want. To be honest, I've never used a switch statement in UnrealScript, but I'll explain them anyway, since everyone's coding style is different. Loops, however, I use all the time. They can be extremely useful to do certain things. There are three types of loops in UnrealScript, which I will explain below.

F o r L o o p s

For loops are the type I use the most, since I've found that they usually fit my needs just as well or better than the other two types. The basic concept of a for loop is to execute a certain block of code over and over again, until a certain condition is met.

For Loop Example

var int i;

for ( i=0; i<5; i++ )
{
    Do stuff;
}

The first statement in the parenthesis, "i=0", sets the initial value of i as the loop starts. The second statement, "i<5", is the condition that must be met for the loop to continue executing. As soon as i is greater than or equal to 5, the loop will terminate. The final statement, "i++", is what is done to i each time the loop executes. So, the first time this loop executes, i will equal 0. The next time, i will be incremented by one, making it equal 1. This is still less than 5, so the loop executes again. Next time, i will be 2, then 3, then 4, and finally 5. The loop will terminate once it gets to 5, since 5 is not less than 5.

D o L o o p s

Do loops, unlike for loops, have no built-in expressions for incrementing counters or setting initial values. They simply execute over and over until a condition at the end of the loop is met. Because they have no built-in expression for incrementing a variable, you will have to include a line within the loop that somehow increments or changes your counter variable, so that the ending condition will eventually be met. Otherwise, you get an infinite loop. Not a good thing.

Do Loop Example

var int i;

do
{
    Do stuff;
    i++;
} until (i == 5);

You'll notice I included the line "i++;" within the loop. This will increment i each time the loop executes, so it will terminate when i gets to 5. The main distinction of the do loop is the fact that it executes until some condition is true. Both for and while loops execute while some condition is true.

W h i l e L o o p s

While loops are basically do loops, except for the fact that they execute while their condition is true, whereas do loops execute until their condition is true. Again, you'll have to include a line in the loop to somehow increment your counter variable, since there is no built-in expression for this in the loop declaration.

While Loop Example

var int i;

while ( i < 5 )
{
    Do stuff;
    i++;
}

S w i t c h S t a t e m e n t s

A switch statement is basically like a complicated if statement. It allows you to execute different blocks of code depending on the value of a certain variable. Take a look at this example:

Switch Statement Example

var string[32] Developer;

switch ( Developer )
{
    case "Tim":
        Hey, it's Tim. Do something;
        break;

    case "Cliff":
        Look, there's Cliffy.
        Do something else;
        break;

    case "Myscha":
        Where'd Myscha come from?
        Better do something else;
        break;

    default:
        No one here;
        break;
}

Not too complicated. You just supply the variable you want to use for the switch in the first parameter, then write different "cases" depending on the different values of the variable. The final "default" label is optional, and will be executed if none of the other cases are true. Note the break statements marking the end of each case.

Like I said before, switch statements are basically just complicated if statements. I rarely have use for them, since the same effects can be achieved simply by using an if/else if/else.

F u n c t i o n s

I have a little confession to make. You know all the examples I've been giving so far, in which I declare a variable or two, then jump right into some code, such as assigning values to these variables, or writing an if statement or a loop? Well, that was illegal. In actual UnrealScript, you cannot just write code by itself. The only parts of a class that can be completely on their own are the class declaration, variable declarations, and exec commands. Everything else must be part of a function or state.

So, what's a function, you ask? A function is just a block of code that performs some action. Once they're defined, they can be called in other parts of the code, to do whatever it is they're supposed to do. They can be given, or passed, variables when they're called, and they can return values. I know this all probably sounds very complicated (assuming you've never done any programming before), but it's really fairly simple once you understand it. Take a look at this example:

Simple Function Example

var int SomeInt, Result;

//Take an integer, and return its square
function int Sqr( int Num )
{
    return Num * Num;
}

//Test the Sqr() function
function PostBeginPlay()
{
    SomeInt = 3;
    Result = Sqr(SomeInt);
}

There are two functions here, Sqr(), and PostBeginPlay(). Sqr() takes a number, Num, multiplies it by itself, and returns it. You'll notice that I didn't declare Num up with SomeInt and Result. This is because it is "declared" as a parameter to a function. When I call Sqr() down in the PostBeginPlay() function, I supply SomeInt as the value in parenthesis, or the parameter. The call to Sqr() causes the code contained in the Sqr() function to be executed, with SomeInt plugged in for Num. You'll also notice that I put the call to Sqr() after "Result =". This is because I am assigning the value which is returned by Sqr() to Result. When all this code is done executing, Result will be equal to 9: the square of 3. You may also have noticed the keyword "int" before the function name in Sqr()'s definition. This "int" means that Sqr() returns an integer value.

Anyway, you may be wondering by now, Where is PostBeginPlay() being called from? The answer is, the engine. There are a wide variety of functions in UnrealScript which are called by the engine in certain places and under certain circumstances. The PostBeginPlay() function is called when an object is first created, so it makes a good place to put code that you want to be executed before any other code. For a list of common functions which are called by the engine (as well as other useful functions which aren't called by the engine), refer to the Function Reference at the side of this page.

So, are you thoroughly confused yet? If not, then you're doing good. I know I was scratching my head quite a bit when I first learned this stuff. Well, keep reading, it gets better (or worse, depending on your viewpoint). You know the way I've been declaring variables all along? At the beginning of a class, using the syntax "var [vartype] [varname]"? Well, that's not the only way you can declare a variable. That type of variable, declared outside of any functions, is called a global variable. Global variables can be accessed anywhere in a class, and even outside of a class (as we'll see a little later). But, there are also local variables. Local variables are declared at the beginning of a function, and can only be accessed within that function. They're useful for doing short-term operations that won't need to be "seen" outside of a particular function. You see, one of the key elements of a function, and of object-oriented program as a whole, is the fact that a class or function can share useful data and important information with other classes and functions, but hide how they got that useful data and information. They show only the result, but not how they found the result. In any case, where was I going with this? Oh, yes. Local variables. Local variables are declared just like global variables, only they use the local keyword instead of the var keyword.

Local Variables

function PostBeginPlay()
{
    //Declare a local integer
    local int SomeInt;

    //Assign a value
    SomeInt = 3;
}

So, that's a local variable. Not too complicated, is it? Just like a global variable, except for the fact that it can only be accessed inside a particular function.

I n h e r i t a n c e

Inheritance, you ask? What could inheritance possibly have to do with programming? Well, it has a lot to with programming. At least when you're talking about classes. If you'll remember, I told you earlier that one of the reasons classes are arranged in a hierarchy is that child classes inherit code from their parent classes. Well, I wasn't just saying that to watch myself type. A class will inherit all variables, functions, states, and default properties (I'll talk about states and default properties a bit later) from every class above it in the hierarchy. For example, the Weapon class has in it all the code written in the Inventory class, the Actor class, and the Object class, since these are the classes above it in the hierarchy.

Any new code you write in a class is simply added on to the code inherited from parent classes. But what if you wanted to change a certain inherited function? Well, you can. It's called overriding a function. All you have to do is copy the function definition into the new class (the name, parameters, and return value type), and write new code for it. The ability to do this is extremely useful in UScript, since it allows you to add or change functionality in things without having to copy over all the code. For instance, say you wanted to make an ASMD that launched grenades in alt-fire instead of the little blue energy ball thingy. All you would have to do is copy the one function that controls what happens when the player presses alt-fire, and make a few little changes. Nothing to it.

S t a t e s

No, not the United kind. We're talking about UnrealScript here, remember? Anyway, a state is simply a section of code that is executed only the class is in that state. For instance, what are the different states that a weapon could be in? It could be firing, alt-firing, reloading, or just sitting there looking pretty. Each of these conditions could have their own state defined for them, which would contain code that's only used when the weapon is in that condition. For instance, if you wanted a weapon to play an idle animation every 30 seconds, you could put a looping timer in the idle state, so it would only run when the weapon was not doing anything. To give you an idea of how they're defined, here's the actual Idle state from the Weapon class:

The Weapon Idle State

state Idle
{
    function AnimEnd()
    {
        PlayIdleAnim();
    }

    function bool PutDown()
    {
        GotoState('DownWeapon');
        return True;
    }

Begin:
    bPointing=False;
    if ( (AmmoType != None)
        && (AmmoType.AmmoAmount<=0) )
        Pawn(Owner).SwitchToBestWeapon();
    if ( Pawn(Owner).bFire!=0 ) Fire(0.0);
    if ( Pawn(Owner).bAltFire!=0 ) AltFire(0.0);
    Disable('AnimEnd');
    PlayIdleAnim();
}

Code in states can be written either within functions, or under labels. Begin is by far the most common label, and any code written under it is executed as soon as the class enters that state. Another cool thing about states is that you can use them to override functions within a particular class. For instance, say you had a Timer() function defined outside of a state. If you defined another Timer() function within a state, then that Timer() function would override the global one if the class was in that state.

Another useful thing you can do with a state is to stop certain functions from executing while the class is in that state. For example, if you wanted to make it so the player couldn't fire while his gun was reloading (usually a good idea), you could add this line just after the definition of your reload state:

The Ignore Statement

ignores Fire, AltFire;

This makes it so neither the Fire() or AltFire() function can be executed while the class is in this state. To make an object enter a state, use the syntax: "GoToState('State');".

D e f a u l t P r o p e r t i e s

Default properties are simply a means by which you, as the programmer, or someone else, such as a mapper, can set default values for certain variables in a class. Default properties are used to control many things, such as how to display a class, what mesh or texture to use, and what sounds to use. If you want a variable to be displayed in the default properties of a class, you have to declare it in a special way:

Default Properties Variable

var([defaultgroup]) [vartype] [varname];

The part in the parenthesis, defaultgroup, tells Unreal what section of the default properties you want the variable to be displayed in. If you don't supply anything for this parameter, it will be displayed in a section with the same name as the class. You can look at and change the default properties of a class by selecting it in the class browser, and clicking the "Defaults" button.

Y o u r F i r s t C l a s s

Here it is. The moment you've been waiting for since... since... well, since you started reading this sentence, I suppose. It's time to create your first new UnrealScript class. To be specific, you're going to make a new type of FlakCannon that randomly alternates between firing a flakshell, a grenade, or an energy ball in alt-fire. Not the most exciting weapon there ever was, but hey, this is a tutorial for beginners.

To start off, I suppose I should explain a little something about the way Unreal is organized. All classes, sounds, textures, and models are stored in special files called packages. Most of the code and models, and some of the textures and sounds for Unreal are stored in two files: unreali.u, and unrealshare.u (as of 220, anyway). These files are found in your Unreal\System directory, as are all .u files. When you create a new class in UnrealScript, you store that class in a new .u file. It's not a good idea to store a new class in an existing .u file, since you would then have to pass around the entire file if you wanted to distribute your class.

With that out of the way, let's get ready to rumble. Open up UnrealEd (if you don't already have it open), and get to the class browser. Open up the Inventory and Weapon threads, and select the FlakCannon class. Now, hit the "New..." button, which can be found down below the browser. You'll get a window asking you to enter a class name, and a package name. Enter "MultiCannon" in both fields, and press the "Create this actor class" button. You'll see that your MultiCannon class will appear under FlakCannon in the class tree, and an editor window will appear, complete with the class declaration.

The next thing to do is copy the AltFire() function from the FlakCannon class, since we want to modify what the weapon shoots in alt-fire. AltFire() is simply a function which is called by the engine when the player presses the alt-fire button. It's used to control what happens when a weapon alt-fires. The same goes for the Fire() function, but we're not modifying primary fire here, so we don't need Fire(). Anyway, double-click on FlakCannon in the class browser to open it up. Scroll through the code until you find the AltFire() function, and copy it into your MultiCannon class. You'll notice that the new code appears as all green when you first copy it. This is because UnrealEd doesn't apply the proper coloring to code until you compile it. So, let's compile it. Compiling in UnrealEd couldn't be easier. Simply hit the F7 key to compile all modified classes.

Now, add the following local variable declarations to your new AltFire() function:

New Variable Declarations

local projectile p;
local class<projectile> Proj;
local float Selection;

Next, find the line "Spawn(class'FlakShell',,, Start,AdjustedAim);", and replace it with the following lines:

New Code

Selection = FRand();
if ( Selection < 0.4 )
    Proj = Class'FlakShell';
else if ( Selection < 0.7 )
    Proj = Class'Grenade';
else
    Proj = Class'TazerProj';
p = Spawn(Proj,,, Start,AdjustedAim);
if ( Proj == Class'Grenade' )
    p.DrawScale *= 1.5;

That's it. Those are all the modifications that need to be made. Hit F7 again to compile the changes, and you're set. So, what does all this code do, you ask? Well, it's simple, really. Selection is set equal to FRand(), which returns a random number between 0.0 and 1.0. Then, an if/else if/else is used to set Proj to either FlakShell, Grenade, or TazerProj, depending on the value of Selection. Whatever Proj is set to is then spawned (Spawn() is a function that brings a class into existence in the Unreal world), and at the same time, p is set equal to this new projectile.

Now, here's something I haven't explained quite yet. The line "p.DrawScale *= 1.5;" is used to reference a variable called "DrawScale" in p, and assign it as itself times 1.5. This is useful notation. If you want to reference a variable or function in another class, all you have to do is specify which class it's in by putting the name of the class, followed by a dot and the name of the variable or function.

So, that's it. Your first new UnrealScript class. Before the MultiCannon package will actually be written to your hard disk for use in-game, though, you'll have to save it. Hit the "Save" button at the bottom of the class browser, and select "MultiCannon" in the pull down menu of the window that appears. You'll need to do this every time you make any changes to one of your classes. Now, to try out your work in a game, start up Unreal, go to the console, and type "summon multicannon.multicannon"

Good luck, and I hope to see some kick ass weapons from you :)


Beginner's Guide to Using UnrealScript

Beginner's Guide to Unreal Using UnrealScript

Purpose

In this document I will attempt to provide an introduction to programming for Unreal using Unrealscript and outline the basic class structure that Unreal uses. This is intended for beginners who are looking for a starting point in creating Unreal modifications. I strongly suggest also reading Tim Sweeney's "Introduction to Unrealscript", (included in the reference section - eko) as this document is more specific in the application of Unrealscript to Unreal, and his introduction is more general to Unrealscript. This will not cover the use of header files and other libraries, as it is not currently available to the public at the time this document was written. Comments, suggestions, praise should all be sent to Ray Davis via email at ca@planetunreal.com". Thanks go to Tim Sweeney, Steven Polge, and the rest of the Epic team for making a cool game, and being cool developers who actually respond to questions. You guys rock. :-)

Introduction

Unrealscript is a language developed solely for developing game content for Unreal. It is based on Java and C++, so if you have any experience in either of those languages, or just C, the learning curve for Unrealscript will be relatively small, but if you do not have any previous experience I strongly suggest that you first learn one of those languages and then return to Unrealscript. Unrealscript adheres to a syntax style common to both Java and C++/C, sharing many keywords found in Java.

Unrealscript is an Object-Oriented-Programming language (OOP for short), which means that it is based on the concept of classes and inheritance. It is important to note that Unrealscript doesn't have all the features of a more complete OOP language such as Java, mainly it doesn't support things like multiple-inheritance, but luckily none of these missing features are necessary to make a fully functioning modification. There are several tutorials that will quickly get you acquainted with the concept of OOP if you are unfamiliar with it, Brandon Reinhart's being one that can be found here.

A unique feature to Unrealscript that is not found in either Java or C++ is states. States are a feature that allows you to define different implementations of functions within the same class (very similiar to function overloading in OOP), and generally they are used for time-based programming. For example, say you had a Player class that contained 3 states, Walking, Running, and Idle. Say that you wanted the Player to do a flip in the air if he jumps while running, and that you didn't want to have him jump at all while standing still (or Idling). One way to do this using states is to define your jump function in both the Running and Idle states, then in the Running state code a simple flip in that version of the Jump function, and then code a standstill in the Idle state's version of the Jump function. So now when your player is running (and thus in the Running state) it will do a flip if it jumps, and will do nothing if its not running. Sorry if this isn't a very good example, but it should help make it a bit clearer how states can be very useful.

Unreal stores Unrealscript code into packages (optionally along with textures, sounds, and models) in your Unreal\System directory. To keep all your new classes in a single package for easy distribution, just specify the same package name in the package field when you create your new subclasses.

Using Unrealed to edit UnrealScript

Unrealed has a builtin class browser, editor, and compiler for Unrealscript which is easily accessible. Start up Unrealed normally and on your right there should be a collapsable tree starting with "+Actor" and having several other classes underneath it such as "-Brush" and "-Info". By clicking on the "-" or "+" next to a classname you can collapse/expand the class tree to show its child classes, and by double-clicking on the class name itself it will bring up an editable window with the class code (if there is any) inside it. By right-clicking on the class name you can bring up a small menu that allows you to create a subclass of the current class or edit the default properties. NOTE: For most modifications you will want to subclass pre-existing classes and save them to your own packages, because if you modify the original Unreal code you will not be able to play with other versions of Unreal due to mismatches (mainly as a cheat preventing measure I believe).

To compile and save newly edited code just press F7 to compile all changed scripts, and then at the bottom of the tree select save, find you package, and click on save. Unrealed will then save you code (compiled or not) into a file in your Unreal\System directory by the name of your packagenamge and a ".u" extension (i.e. "blah.u" for the blah package).

Unreal's Class Structure

Object and Actor

Everything that is coded Unrealscript is derived from a very abstract and basic Object class, and from that we get many internal classes that deal with the engine itself (mainly sound, graphics, etc) and more importantly the Actor class which pretty much encompasses all of what you will want to modify for partial modifications. The Actor class defines the majority of standard variables and functions that are necessary for all classes, and all game-content related material is contained in classes derived from Actor. Players, weapons, artificial-intelligence, and even the game itself is derived from the base class of Actor. Important functions to note in Actor are BeginPlay(), Spawn(), Touch(), Tick(), and Destroy(). The BeginPlay() function is called whenever an instance of this class is put into play, into the game. It is very useful to initialize important variables and do other actions at the point of creation. The Spawn() function is used to create an instance of a class and put it into play. Touch() is called whenever this actor is touched by another actor, and is useful for causing damage or altering variables in the other actor. The Tick() function is called every game tick, generally as much as possible, so use it to perform actions continously or check for certain conditions. NOTE: Be careful not to put too much code into a Tick() function because it is very easy to overload the game and cause noticeable lag if too much is going on. Use the Destroy() function to destroy this instance of the class when you no longer want it to be in play.

Pawns

The Pawn class contains the ScriptedPawn (AI), FlockPawn (Insect/Flock AI), PlayerPawn (Players), and more recently the Bot classes, essentially all of the "living entities" in a level. The Pawn class defines basic variables, movement and other miscellanous functions common to all Pawns. Health, Groundspeed/Airspeed, and JumpZ are just some of the useful variables found in all Pawns.

PlayerPawn encompasses all players, a.k.a. clients, that are available in the game. It has several child classes, mainly UnrealIPlayer, then Human/Skaarj, and then the various male/female players. PlayerPawn contains all of the functionality of the players (movement, input handling) while the rest of the children classes handle all of the animations and sounds specific to the various players. The PlayerInput() and PlayerCalcView() are two functions that can be altered in your own classes to create some very cool modifications. PlayerInput() handles all input from the player, calls pertinent functions, and modifies appropriate data. PlayerCalcView() handles the calculations of the view of the player, and can easily modified to create a third person view, etc.

The ScriptedPawn is where you will find all AI-related game content (the exception being FlockPawns). This class defines the framework which Unreal's Skaarj, Nali's, Queen, and every other creature you will find in the game. The AI uses states heavily, and is based upon the common pathnode-using technique for navigation. Thankfully Steven Polge is a very good programmer, and has designed a very robust AI that can be used to make new creatures very easily with very little to no new code, using editable variables to define all aspects of the AI. I strongly suggest you read Steven Polge's "Unreal Creature Care and Feeding Guide" (included in the reference section - eko)if you plan to do any major AI programming, or if you just want to get a more in-depth understanding of how things work.

FlockPawns are special case AI that powers those wonderful schools of fish and swarms of flies that don't really do much other than look cool. You can modify these to make them a bit more intelligent if you wanted to I suppose, but they are pretty good at being insects already. NOTE: FlockMasterPawns actually handle the creation of FlockPawns, and you should spawn these instead of individual FlockPawns, as they are coded to self destruct if they don't have a FlockMasterPawn.

The Bot class used to be found beneath the ScriptedPawn class, but has since been moved to just a child of Pawn as its AI is noticeably different than average ScriptedPawns in its function and purpose. This is the class to study if you think you've got ideas on how to make more realistic/deadly/unique Bots in Unreal. NOTE: Bots still share the same initial structure as ScriptedPawns, so Steven Polge's AI guide will also be useful for understanding Bots.

Info

The Info class is a generalized class that encompasses all classes that deal with various game-related information, such as the current rules (Deathmatch vs SinglePlayer vs TeamGame), ZoneInfo which is used to create lava, water, or just plain empty space, and PlayerReplicationInfo which contains special networking information for Players. Most of my coding experiences in the Info classes has been in GameInfo to define new game types, or variations on the classics, such as ASMD-only deathmatch. It is also conceivable to subclass the ZoneInfo class to create new types of zones such as toxic goop from Mars, or maybe a specialized case of water that reflects weapon shots, etc.

Triggers

The Trigger class handles the operation of lifts, doors, and other events by responding to certain actions in the game and then performing another action, either by modifying another actor or by setting off other triggers, or both. Triggers are invisible in the game and are generally triggered by touch, proximity, or by another trigger. It is also to call the Trigger() function from another class to set off a trigger, say to open all the doors in a level at once or something. Subclass the Trigger class to create special case triggers, or other event-driven gameplay.

Effects

Effects covers all the special effects in Unreal, like explosions, laser blasts, etc. Subclass effects to create your own special effects, or combine other existing ones.

Inventory

The Inventory class, a child class of Actor, contains both the Pickup classes and Weapon classes. Pickup is all the items other than weapons that a Pawn will pick up and use in a game, be it health, armor, or ammo. Use the Pickup class to make your own unique items in a game, such as can of beans, or maybe even a landmine. The Weapon class handles all the functions for firing and aquiring weapons in a game. All of the individual Unreal weapons are defined as subclasses of the Weapon class, and handle the specifics of the weapons, such as animations and creating the projectiles/weapon effects. Just subclass weapon to create new weapons, provided you have a new model, or you can subclass one of Unreal's weapons and just use its model. NOTE: Weapons are based on an important variable, bInstantHit. If this is set to true, then the weapon will not create a projectile (such as a rocket), and instead will do instant damage to any targets in the line of sight (such as the rifle).

All the rest

There are many classes that are used to create the remaining things you see in Unreal, such as the HUD for players, lights, moving brushes, menus, or new projectiles. Experimentation, and just plain browsing through the code should help you gain a basic understanding of how everything else is layed out and how it works.

Vectors and Angles

Unreal uses the concept of Vectors and Angles to handle all of the movement and rotation of Actors in the 3d game world. A vector is a structure that consists of 3 components, X, Y, and Z values, where the X axis is forward/back, Y is left/right, and Z is up/down. You can modify these values directly to alter an Actors postition in the world, using the SetLocation() function with a new vector for the new location. Rotation is handled by an Angle structure which also consists of 3 components, Pitch, Yaw, and Roll, where Pitch will rotate up/down, Yaw to the left/right, and Roll will roll as though your were tilting your head to the left/right. Using SetRotation() you can alter what direction an Actor is facing, or convert a rotation to a vector to alter the direction of an Actor's velocity, etc.

If you're in college and would like to know more about 3d mathematics, I'd suggest taking some Physics classes and Linear Algebra, as vectors/matrices are common topics. Also try searching online for 3d mathematics tutorials, I know QDevels has a 3d tutorial, as does Weapons of Destruction on PlanetUnreal.

Conclusion

Although I'm sure you probably have many more questions, that is beyond the scope and purpose of this document, but you can find tutorials on more specific applications of Unrealscript at various websites, including Chimeric at http://www.planetunreal.com/chimeric. Also, make sure you frequent the Unreal Technology Page at http://unreal.epicgames.com, as it contains the latest news from the Unreal development team, and contains a lot of useful information.


rogerbacon2

UT Skins Importing

by Shane Caudle

Shane@Scott.Net

Importing Skins into UnrealEd Tutorial

In this tutorial I'll show you Step By Step how to import all the pcx's and bmp files that I released in a sample skin I did called OverKill. You can get it here.

Step 1

First you need to make sure you are in Texture mode under the browser.

Imp-Browse.jpg (18155 bytes)

Step 2

Now, at the bottom of the browser click on Import.

Imp-Import.jpg (16001 bytes)

Step 3

Now, select all the files you want to import. Just select all the Pcx's for now.

Imp-Files.jpg (57216 bytes)

Step 4

Now, name the package as Test and make sure Generate Mipmaps is turned ON, then click Ok to All.

(Use the name "Test" because there is a 15 character limit to the length of the Package name while importing it, you will re-name it later to SoldierSkins_OkerKill when you save it)

Imp-Files2.jpg (33192 bytes)

Step 5

Now at the bottom of the browser click on Import again.

Imp-Import2.jpg (16229 bytes)

Step 6

Now, select all the Bmp files you want to import.

Imp-Files3.jpg (50727 bytes)

Step 7

Now, leave the package name as Test and turn Generate Mipmaps OFF click Ok to All.

(The reason we want Mipmaps off is because we don't want the texture LOD to use Mipmaps on these chat faces because the are part of the HUD)

Imp-Files4.jpg (34107 bytes)

Step 8

Now, click Save .

Imp-Save.jpg (18367 bytes)

You will want to re-name the Package from Test to SoldierSkins_OverKill.

Imp-SaveAs1.jpg (53862 bytes)

Once you re-name it click Save.

Imp-SaveAs2.jpg (57004 bytes)

That's it, you now have a SoldierSkin_OverKill.utx in your UnrealTournament/Textures directory.

All you need to do now is make sure you have the SoldierSkins_OverKill.int file in your UnrealTournament/System directory and you now can use this skin.


UWindows Help

UWindows Options

Mutators with configuration options should make their own UWindow subclasses for configuration, and insert themselves into the (usually invisible) Mods menu, instead of using advanced options. Here is a really basic outline of how you'd go about it. I haven't compiled this code but it's pretty much everthing you should need to do. (JbP: I've since compiled the code. It works :) When I get some time I hope to document the uwindow classes so it's a bit more obvious where to start doing stuff like this.

MyMutatorConfigWindow

class MyMutatorConfigWindow expands UWindowFramedWindow;

function Created()

{

Super.Created();

SetSize(150, 100);

WinLeft = (Root.WinWidth - WinWidth) / 2;

WinTop = (Root.WinHeight - WinHeight) / 2;

}

defaultproperties

{

ClientClass=class'MyMutatorConfigClient'

WindowTitle="UDamageArena Configuration!"

}

MyMutatorConfigClient

class MyMutatorConfigClient expands UWindowDialogClientWindow;

var UWindowCheckBox SomeCheck;

function Created()

{

Super.Created();

SomeCheck = UWindowCheckBox(CreateControl(class'UWindowCheckBox', 10, 10, 100, 1));

SomeCheck.SetText("Some Option");

SomeCheck.SetFont(F_Normal);

SomeCheck.Align = TA_Left;

SomeCheck.bChecked = class'MyMutatorClass'.default.bSomeOption;

// You could of course add heaps of controls in here.

// See the UMenu and UTMenu for a billion examples.

}

function Notify(UWindowDialogControl C, byte E)

{

switch(E)

{

case DE_Change:

switch(C)

{

case SomeCheck:

class'MyMutatorClass'.default.bSomeOption = SomeCheck.bChecked;

class'MyMutatorClass'.static.StaticSaveConfig();

break;

}

break;

}

}

MyMutatorMenuItem

class MyMutatorMenuItem expands UMenuModMenuItem;

function Execute()

{

MenuItem.Owner.Root.CreateWindow(class'MyMutatorConfigWindow', 10, 10, 150, 100);

}

defaultproperties

{

MenuCaption="&UDamageArena Configuration"

MenuHelp="Configure the UDamageArena mutator! Make ALL your pickups UDamages!!!!"

}

The int file

Finally, you need to add this to your mutator's .int file to add yourself into the menus.

[Public]

Object=(Name=MyMutatorPkg.MyMutatorMenuItem,Class=Class,MetaClass=UMenu.UMenuModMenuItem)

-------------------------------------------------

JbP's Notes:

1) The int file has a reference to MyMutatorPkg. This should be changed to the name of your package.

2) To compile the above directly, you will need to create the mutator which these classes reference. It is called MyMutatorClass:

class MyMutatorClass expands Mutator;

var bool bSomeOption;

3) If you've never used ucc to compile uc classes before, the 'defaultproperties' sections above will be unfamiliar to you. They won't compile inside UnrealEd. You will need to compile the above using ucc. Heres the simple explanation:

  1. Go into your UnrealTournament.ini file and find the section containing the EditPackages= statements. There should be about 10 of them. Add EditPackages=MyMutatorPkg at the end of this list.

  2. Make a sub-directory of your UT directory called MyMutatorPkg. Make a sub-directory of this, called Classes.

  3. Save each class as a .uc file in the classes directory. You should have four text files, called MyMutatorMenuItem.uc, MyMutatorClass.uc, etc. The name of the uc file should be the name of the class.

  4. Open up a dos prompt, cd to your UT\System directory, and type ucc make. It should eventually either compile your code or return an error, indicating you need to check your code or your files setup. Warnings will result in compiled code, but if you ignore warnings be prepared for buggy mods.

4) Thanks, Mek!


Vectors and Rotators

This tutorial is rather simple, but important. Vectors and Rotators are vital to the understanding of how items are spawned in UT. This tutorial only attempts to define vectors and rotators as viewed by the spawn function. It may not be accurate in all instances not related to the spawn function, so please keep that in mind.

Since we are going to be looking at vectors and rotators in relation to the spawn function, let's first get a rundown of that function. The prototype is this:

native(278) final function actor Spawn

(

class<actor> SpawnClass,

optional actor SpawnOwner,

optional name SpawnTag,

optional vector SpawnLocation,

optional rotator SpawnRotation

);

When I first looked at the above, it confused the heck out of me, so let me explain it.

The SpawnClass variable is what you want to be spawned, i.e. a Rocket from a rocket launcher or a grenade from a grenade launcher. This is the only parameter that is required. In your code, it will look like this:

spawn(class'yourPack.yourItem');

The SpawnOwner variable is the person who the item is spawned from. Thus, if a player shot a rocket, the rocket's owner could be placed in the SpawnOwner spot. This variable is optional, and most people don't need it. Code:

spawn(class'yourPack.yourItem', yourSpawnOwner);

The SpawnTag variable is confusing even now, and I'm not sure what exactly it does yet.

SpawnLocation is where the item is spawned at in the level. It is a vector, and we will look at it in more detail later. Code:

spawn(class'yourPack.yourItem', yourSpawnOwner,,yourSpawnLocation);

If you noticed, you will see that there are two commas after yourSpawnOwner in the code above. The reason for that is that in order to bypass the SpawnTag variable, you have to include an extra comma to tell UT that yourSpawnLocation is associated with the SpawnLocation variable, and not the SpawnTag variable. I know that sounds confusing, so here is another example:

spawn(class'yourPack.yourItem',,,yourSpawnLocation);

Here, both the SpawnOwner variable and the SpawnTag variable are skipped, thus the extra two commas. I hope this makes it clear to you.

Finally, on to the last variable, SpawnRotation. This is a rotator, and we will also look at this in more detail. First, the code:

spawn(class'yourPack.yourItem',,, yourSpawnLocation, yourSpawnRotator);

I've gone ahead and done away with the yourSpawnOwner variable, as it is hardly used, but you may find a use for it.

Vector Variable SpawnLocation in more detail:

SpawnLocation is where in the level your item will be spawned. It is a vector, and every vector has 3 parts: an X, a Y, and a Z component. The X, Y, and Z of the vector makes up a 3d point in a UT level that the object you spawn appears at. Usually, this is the same location as the actor that spawns the object. Every actor in a level has a default property called Location. To access that point, you would write something like this:

local pawn yourPawn;

local vector spawnLoc;

spawnLoc = yourPawn.Location;

In this code, spawnLoc is set to the point in the level where yourPawn is. Of course this is very simplified code, but you get the idea.

There are a few ways to change the variables contained in a vector. The easiest (but longest) way is to change the individual components individually. Basically:

spawnLoc.X += 3;

spawnLoc.Y += 4;

spawnLoc.Z += 5;

The other way is to change the vector by using another vector:

local vector addVect;

spawnLoc += addVect;

Of course, addVect has to be initialed first, but you get the idea.

You must be careful about just assigning a vector arbitrary values, because you can never be sure where the vector is in the level. If you set a vector in your code to be (0,0,0), then anything spawned using that vector will spawn at (0,0,0)...however, that point may be in the middle of a rock in one level, or right at a team's flag, or whatever. Therefore, most vectors should be used in relation to a point that you can know. Such as taking a player's Location variable, assigning another vector that location, and then modifing the new vector to do what you want.

The final thing is an explaination of the various components of the vector. The X portion of it is the horizontal part. The Y portion is up and down, and the Z portion is horizontal as well, perpendicular to the X component.

Rotator Variable SpawnRotation in more detail:

SpawnRotation defines the direction that your spawned item will travel if it does travel. In fact, the only reason you will need a SpawnRotation is to define the direction that an object will travel, or the direction your object will face (although I'm not sure about the last one). Every rotator has 3 parts: a pitch, a yaw, and a roll. Every actor in UT has a default property called Rotation, which is accessed exactly like the Location variable in the sample code above.

A rotator can also be changed by the same methods as a vector. The only difference is the properties involved:

local rotator newRot;

newRot.Yaw += 3;

newRot.Pitch += 4;

newRot.Roll += 5;

A rotator can be assigned arbitrary values, and a certain value means a certain thing. The Yaw component is used to define the horizontal aspect of the rotator. A full circle is 65,535. You may define a Yaw component higher than 65535, but that will just begin to overlap the same circle that has already been used. For example, if you wanted an object to spin around 2 times, the final value of the Yaw component will be 131070. You can also define negative values, and that is like going around the circle in reverse.

Pitch is the vertical aspect of the rotator. A value of 0 is horizontal. Anything up to 32767 is like the equivalent of 0 to 89 degrees. A value of 32767 is straight up, and anything over 32767 is the equivalent of 91-180 degrees (i.e. the projectile will go backwards). A negative value will make the projectile go down instead of up. Also, anything over 65535 will make the projectile go down as well, until the value passes 131070, and so on and so forth.

Roll I don't really understand yet (I've never used it), but I think it is used to make your projectile spin.

All of the values I've listed above I got from trial and error in coding. They may not be 100% correct, but they are very close.


Your Registry

Your Registry & UT

By Kobain

Kobain3@hotmail.com

Advanced

Yes, I am quite aware that this tutorial has absolutely NOTHING to do with UScript, or anything to do with coding, but I think that there are a few people out there who would appreciate some of the information here.

So, now that we've got that out of the way, let's begin. Oh, and by the way, if your system is running anything other then Windows 9x, then I do not know if this will work. On top of that, if you're running a Linux Box, or a Macintosh, then I suggest that you just skip even reading past this part.

Alright, now we can begin. For those that don't know what your Registry is, here's a brief idea of what it is and what it does. It's a place where Windows, and other programs keeps your options stored. That way, if you have a preference in one program, i.e. key bindings, it can be stored in the Registry, and then if you have another game by that company, they can call up your previously stored key bindings, and preload them. A nifty little bugger, now ain't it? Registry files aren't stored in anyone specific spot, but they're made of various files, including the .reg, .log, .alt, and .sav extension types all over your HD. Try this. Go to Start->Find. Type in "*.*reg" minus the quotes, and make sure your searching the C:\ drive. The return results, are all the current .reg registry files.

Now, let's open up the built-in Windows Registry Editing Program. Go to Start->Run. Type in "regedit", again, minus the quotes. What should open up in a Windows Exploreresque window which has on the left a bunch of prefixes HKEY_whatever, and blank space on the right.

Now, before we go ANY further, I would like to give you a warning. The Registry is a dangerous place for people who don't know what their doing. If you're not careful, you could, in theory, make your computer NOT boot up properly. So, the first thing we're going to do is create a back-up of your Registry in it's current state. To do this, make sure you have My Computer highlighted and go to Registry->Export File Registry... Find a satisfactory spot to save to, name it (I've found Back Up 1 works great), and click Save. Good. Now in the event that you totally screw up (anything could happen, right?) you've got a safety net.

So, now let's begin to explore the wonderful world of the Registry. On the left, we have the class tree. Find HKEY_LOCAL_MACHINE and expand it. Follow it to Software->Unreal Technology->Installed Apps->Unreal Tournament. When you click on Unreal Tournament, you'll notice that the right hand side of the window pops up with some information. Assuming you have the latest patch, this is what you will see:

(Default) | (value not set)
Folder | "C:\UnrealTournament"
Version | "436"

Let's take a look at what each one of these 'keys' and 'values' are. Well, first off a key is the part on the left, which has the name of the value. The value is the variable(s) stored to the key. The first value, (Default) has no value set to it because there are other keys in this folder. Therefore, a default value is a moot point. Folder is where UT is installed. .UMOD files actually look to this value and that's where they like to auto install. Let's try an experiment. Right click "Folder" and go to Modify. in the pop up box, type in "C:\UnrealTournament2". Now run, or quickly download a .UMOD file. Guess where it wants to auto-install. Yup... C:\UnrealTournament2. Isn't the Registry a beautiful thing? Since we don't want that to be the permanent default value, change it back to the original value of "C:\UnrealTournament". Now, let's look at the last key. The Version tells the .UMOD files what version of UT your running. Ever get the message that your not running the right version and you need a patch? Well, this is where it gets the information it needs to recognize that.

Let's go onto a different section of your Registry now. Close HKEY_LOCAL_MACHINE and open up HKEY_CLASSES_ROOT. Start scrolling down. As you do this, you'll notice that all these .whatever folders are actually extensions. If you expand any one of these, you'll actually get the information about what program is associated to each file type. If you've ever hit shift, and then right clicked a file, you'll see a Open With... option on the menu. If you click that another window pops up and allows you to select the program you wish to open the file with. Of course there's defaults, and this is where the default program and the path of the program are all handled. Just for fun, let's expand the .doc folder and take a look at what we see. Highlight the .doc folder and you'll see the default program that opens it up. If you look at the sub-folders, those happen to be other programs which are or were installed that could also open .doc files.

Now, let's relate this all back to UT, shall we? Continue scrolling down the list until you see .umod .umx (assuming you have the plug-in for WinAmp which lets you play .umx files) .unr and .unreal folders. Click on each one to see what they have for values. In each folder you'll see the key (Default) and then the value. This is what they'd look like if they were collectively put together:

.umod | (Default) | "Unreal.Module"
.umx | (Default) | "umx_auto_file"
.unr | (Default) | "Unreal.Map"
.unreal | (Default) | "Unreal.Link"

Individually these may not look to interesting, but if you continue to scroll down to the the u's, you'll see four more sub-folders. They are named unreal, Unreal.Link, Unreal.Map, and Unreal.Module. Umx_auto_file is also there, but because it's not for everyone, I'm going to omit it. So, let's go through each one of these four sub-folders and expand them as much as we can. Once your done, you'll notice that all the sub-folders within the sub-folders have an identical lay-out. Despite the similarities in the lay out, they are not as identical in purpose as it would appear.

Let's start with the unreal folder. If you click on the master folder here (called unreal) you'll see the information for it on the right. It contains a default key, and a value for it. "URL:Unreal Protocal" is the value. So, lets move to the next sub-folder, DefaultIcon. Before we go any further, I just want to make sure you know something. If you open up a web browser, and type in place of the "http://www.whatever.com" and replace it with "Unreal://xxx.xxx.xxx.xxx" and you fill the xxx's with the IP address of the server you're looking for, it will automatically connect & launch UT. Well, the same rule applies if you create a shortcut on your desktop. Try this. Right click on your desktop and go to New->Shortcut. Fill in all the information as you will, but for the "Command Line" put in "unreal://255.255.255.255". Once you're done, the icon will switch to the UT icon! Amazing! Now, let's say you want to change that default icon. Back to the Registry. In the Unreal->DefaultIcon folder, you will see a value for (Default) which happens to be the address of the icon (a .ico file). If you create your own icon, (not too hard to do) you can type in the address of the icon there, and the default values for the shortcut will be changed to whatever you want. It's handy if you have a series of clan or favorite servers that you enjoy. You can create an icon for UT servers, and the shortcuts then keep them all in "My Documents."

Let's continue to explore here. The next folder is Shell, followed by open and then command. The only really point of significance is in the command sub-directory, you have the command line for the UnrealTournament.exe. This would come in handy if you have installed multiple copies of UT and you want one copy to be your bitch copy, and you want the other to be 'pure.' It's not that weird. Honest!

So, we've taken a look at unreal, let's move onto Unreal.Link, Unreal.Map, and Unreal.Module. Actually, if you are familiar with C++ or UScript, you'll recognize the '.' indicator in regard to classes. If you have no idea what I'm talking about, don't worry about it. It's not really important. In reality, all these keys have nearly identical purposes, but for different aspects of the Unreal Engine. The first file tells what it's for, the DefaultIcon give the address for a default icon for that type of file, open gives the open command (right click a .unr file and look at what it says... Play This Unreal Map.) and command gives the run command for what program opens this file extension. The really cool thing you can do here is that you can change what the open value is. Let's try this. Change the Unreal.Module->Shell->open value from "&Install This Unreal Module" to "&Run The UMOD Now!" Now, go to a .umod file and right click it. Guess what you see. Cool, eh? This also applies to the Unreal.maps and Unreal.Link.

Now, there's one other section in the Registry we can hit. It has a lot more as far as values and keys, but not as much stuff to do. So, let's close HKEY_CLASSES_ROOT and open up HKEY_CURRENT_USER. Scroll down to Software, and expand. Keep going till you see Unreal Services. This is what we're looking for. Expand every single folder and sub-folder here. A lot of the values in these folders are meaningless, and are used in the engine and never really affect us. However, if you go to Unreal Services->Players. You'll see one or more folders. It actually depends on how your computer is set up. If you are on a network, you have to log onto Windows 98, and a new profiles is set up for each Win98 profile. Since the majority of people out there will only have one folder in there named with a series of numbers and "#" signs, I'm not going to bother trying to say it's name, but just open it. Inside, you'll notice the skin, face, voice and class strings stored to different keys. So, let's say you would like to alter one, this is where you CAN go. Not really the easiest way, but it's an option. The only other sub-folder here of real interest is the Unreal Services->Unreal Options. In here, there is a key by the name of NickName_Text. It's value happens to be your UT name. This is a good way you can enter symbols for your screen name since there's not really good way to get those into UT. For example you can have K¤båïñ be your super l33t name. All you have to do is open up your Character Map (Start->Programs->Accessories->System Tools) and start picking symbols to be used.

Well, I guess now I've passed on my wisdom regarding the Registry and UT. I hope that you find at least some of this beneficial to you in the future. Oh, and by the way, if you end up messing up something, you can always RESTORE you backed up registry by going to Registry->Import Registry File... In the event that you decided to be cocky and not create a back up, yet you still managed to screw up, there is another way to restore your settings. Reboot your computer into DOS, and type at the C:\> prompt "scanreg /restore". Just like that, except no quotes. From the menu that comes up, select the .cab file with the most recent date, and click restore. Essentially, scanreg /restore, is a way to restore registry settings that are saved every time you turn on your computer. Microsoft actually made a smooth move with that in my opinion. Every time you boot up, Windows saves all the settings that you have to a .cab file. Then, if you mess up anything you can essentially "turn back the clock" on your system. Comes in handy when your screwing around with new software.

Alright, NOW I've finally passed on all my valuable wisdom regarding the Registry. Put it to use, and if you learn anything, feel free to e-mail me about it. Kobain3@hotmail.com is the address. I would be exceptionally interested if anyone knows how to restore an uninstall path for UT. I've been having problems with that, but If anyone has an answer, I'll be glad to add it to this tutorial and give you credit. Have fun! Don't screw up your Registry too much!


Airstrike

by Crack Addict

The goal here is to create a trigger that a player can run up and touch to cause an airstrike, which is basically the creation of a volley of missiles pointed at a specified target. I made a subclass of Trigger and overrode the Touch() function so as to create the missiles, and use the Event/Tag variables to determine our target. This way a level editor could put this trigger in his/her level and set a desired target somewhere else, adding a cool nifty feature specific to that level.
// ===========================================
/ AirstrikeTrigger
// ===========================================

class AirstrikeTrigger expands Trigger;

// Here are some variables to make the trigger easier to
// configure. MissileType is the class of missile that
// will get spawned, NumOfMissiles is the amount to create,
// Height is how high above we should create them, and offsetDist
// will determine the range of the target they should be
// created in.
var() class MissileType;
var() int NumOfMissiles, Height, OffsetDist;

// Touch() is where all the fun stuff happens. First we check
// to see if we have a specified target, otherwise we just default
// to ourselves. Then we go about the process of spawning the
// missile(s).
function Touch( actor Other )
{
local Projectile Missile;
local vector StartLocation, Offset;
local rotator AimDirection;
local int i;
local Actor a, StrikeTarget;

// Just use a foreach to go through all the Actors in the game
// to see if one has the matching tag...
foreach AllActors(class'Actor', a)
{
if (a.Tag == Event)
StrikeTarget = a;
}

// If we didn't find a target, we become the target
if (StrikeTarget == NONE)
StrikeTarget = self;

// IsRelevant() is a function in Trigger that will determine
// if the actor that touched us meets the criteria to trigger
// us. So if a level editor configured this trigger to be
// only triggered by only the blue team or whatever, IsRelevant()
// would make sure that happens.
if( IsRelevant( Other ) )
{
// We've been successfully touched by the right person (kinky)
// so lets go about spawning our missiles.
for (i = 0; i <= NumOfMissiles; i++)
{
// Offset is a random vector generated to keep all the missiles
// from starting in the same place. VRand() generates a vector
// in a random direction, and we just multiply this times a
// random distance determined using the RandRange() function.
// RandRange() simply generates a random number between a Min
// and Max.
Offset = VRand() * RandRange(OffsetDist * 0.5, OffsetDist * 1.5);

// Our start location is simply the target's location plus the
// desired height and the Offset vector we just generated.
StartLocation = StrikeTarget.Location + (vect(0,0,1) * Height) + Offset;

// AimDirection is found by subtracting out destination from our
// starting point, with the destination being the Target's location
// plus the offset.
AimDirection = rotator( ((StrikeTarget.Location + Offset) - StartLocation) * 10000);

// Now that we know everything, go ahead an spawn the desired
// missile. Note that we set the owner to Other, which is the
// actor that touched us, so anybody who dies from an airstrike
// will count as a frag for Other.
Missile = Spawn(MissileType,Other,,StartLocation, AimDirection);
}
}

// Make sure to call the normal trigger code so that we don't break the
// previous functionality of the trigger.
Super.Touch(Other);
}

defaultproperties
{
NumOfMissiles=15
Height=450
OffsetDist=500
}


Bullet Holes

by ^Soul^

Here is some quick code I did for a project i'm currently apart of. Use it as you like, however i'd be pleased to know what you use it for. Its fairly generalized and you can use it for bullet holes, scorch marks, blood splatters etc..etc.. It is a modified ProcessTraceHit(), so its called by TraceHit(), now it doesn't have to be used by trace hit, you could copy it into a projectile's HitWall() for a rocket/grenade/etc, but i'd suggest if your using a projectile to still call TraceHit() and leave the code here as is, for better reliability.
function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal,
Vector X, Vector Y, Vector Z)
{
// This is a container for the Bullet Hole effect
local actor BH;

// This var will be used later to determine the floor
local Float FloorNormal;

// This dot product returns a float number -1.0 is the
// ceiling, 1.0 is the floor, 0.0 is a wall..this of
// course assumes the surfaces are flat
FloorNormal = HitNormal Dot vect(0,0,1);

// you don't want it to appear on people, or their dead bodies =)
if ((!Other.Isa('Pawn')) && (!Other.IsA('Carcass')))
{
// And it looks like crap on the floor if the texture is like
// grass or somthing so don't draw it
if (FloorNormal < 1.00)
{
// Do the Deed =P
// HitEffect is declared elsewhere as:
// var() Class HitEffect;
BH = Spawn(HitEffect,,,HitLocation);

// Make it stick to the obj
BH.SetBase(Other);

// the gfx used was to big, so i shrank it
BH.DrawScale /= 10;
}
}
}


Capture The Flag

by crack_addict

Note: This was made for Unreal, before UT was released and came with Capture the Flag builtin, so its now kind of obsolete, but I've retained it simply because its a good exercise in making a new gametype.

This tutorial covers 3 basic classes used to make a Capture the Flag game, CTFGame, FlagSpawnPoint, and Flag. CTFGame is a GameInfo that handles the startup of games and is a subclass of TeamGame. FlagSpawnPoint is a NavigationPoint that handles the creation of the Flags in a level. Flag is a Pickup that is the flag(s), and it takes care of checking for captures...etc.

This tutorial covers how to make a *basic* Capture the Flag game with very basic scoring and other rules. Feel free to use this as a base to add CTF support to your modification, and if you make money off of it, at least think kindly of me if you're too stingy to send me the money. :)
//=====================================================
// CTFGame - Capture the Flag GameInfo
//=====================================================

Since Unreal already has a Team game setup, and CTF requires teams, we only need to subclass the TeamGame class in order to get team support in. In this class we need to make sure the flags get spawned, and handle scoring for teams/individuals.
class CTFGame expands TeamGame;

The number of points to award to the player and team upon a successful capture.
var() int CaptureScore;

In PostBeginPlay() we search for all FlagSpawnPoints and tell them to spawn a flag. NOTE: This requires that maps need to have FlagSpawnPoints already placed in them in order to properly spawn flags (although you could easily write some code to play FlagSpawnPoints if none are present).
function PostBeginPlay()
{
clocal FlagSpawnPoint fs;

foreach AllActors(class'FlagSpawnPoint', fs)
{
fs.SpawnFlag();
}
}

ScoreTeamCapture does exactly what the name implies, it scores points for a capture.
function ScoreTeamCapture(byte Team, PlayerPawn Scorer)
{

TeamInfo is a class (under the Info class) that is used to store pertinent information about different teams in a Team game. We need to use it to add points to the entire team, as well as the individual capturer.
local TeamInfo ti;

Find a matching TeamInfo based on Team and then give them some points.
foreach AllActors(class'TeamInfo', ti)
if (ti.TeamIndex == Team)
{
ti.Score += CaptureScore;
break;
}

And finally award the person who did the actual capture.
Scorer.PlayerReplicationInfo.Score += CaptureScore;
}

DiscardInventory is called whenever a Pawn dies, and since we don't want a flag destroyed if a player dies we must override this to put it back to its original position. NOTE: It would be a good idea to expand this to drop the flag wherever they died and only send it back after a certain time or if it is touched by a player of the same team. (as in Quake2 CTF and others)
function DiscardInventory(Pawn Other)
{
local Inventory Inv;

Use FindInvetoryType to get a reference to the flag if the pawn has it, and if so drop it.
Inv = Other.FindInventoryType(class'ctf_ca.Flag');
if (Flag(Inv) != None)
{

DropFrom drops the Inventory item at the specified location and handles removing the item from the player's inventory.
Inv.DropFrom(Flag(Inv).InitLocation);
}

Let the normal DiscardInventory do its work now that we've done what we needed.
Super.DiscardInventory(Other);
}

defaultproperties
{
CaptureScore=10
bSpawnInTeamArea=True
}

//==================================================
// FlagSpawnPoint - Flag Spawning Point
//==================================================

This class should be placed where you want the flags to be in the level. The SpawnFlag() function is called at the beginning of the game and creates the actual flag. NOTE: Since FlagSpawnPoint is a subclass of NavigationPoint it will be part of the pathnode table of a level, and as such will be usuable by bots, so it should be relatively simple to alter Unreal's bots to play CTF.
class FlagSpawnPoint expands NavigationPoint;

TeamNumber should be set to the owner Team
var() byte TeamNumber;

MyFlag is a local reference of the flag spawned
var Flag MyFlag;

SpawnFlag() just creates the flag, then sets the Team and InitLocation variables.
function SpawnFlag()
{
MyFlag = spawn(class'ctf_ca.Flag');
MyFlag.Team = TeamNumber;
MyFlag.InitLocation = Location;
}

defaultproperties
{
}

//===============================================
// Flag - CTF Flag
//===============================================

This is a normal Pickup item, and we alter the Pickup state (the Touch() function in particular) to check for flag captures...etc. It is created by a FlagSpawnPoint, and it handles the majority of the CTF game code itself.
class Flag expands Pickup;

Team and Initial location
var byte Team;
var vector InitLocation;

auto state Pickup
{

Touch() is called whenever an Actor collides with this Actor, and normally for a Pickup item it would handle adding this item to the inventory of the Pawn if possible. We alter it to see if the PlayerPawn touching us has a flag (for a capture), or if the PlayerPawn is on an opposite team we give the flag to them like a normal item.
function Touch( actor Other )
{
local Inventory Copy, EnemyFlag;

If it isn't a playerpawn then can't grab the flag. NOTE: Might be a good idea to change this to Pawn, or add a check for Bots if you want to add Bot support.
if (!Other.IsA('PlayerPawn'))

return;

If it is on the same team as us then go ahead and check for a capture.
if (PlayerPawn(Other).PlayerReplicationInfo.Team == Team)
{

Check for capture by seeing if they have a flag.
EnemyFlag = Pawn(Other).FindInventoryType(class'ctf_ca.Flag');
if (EnemyFlag != None)
{

Score points, reset flag, and let the world know about it.
BroadcastMessage(PlayerPawn(Other).PlayerReplicationInfo.PlayerName
$ " captured the enemy flag!");
CTFGame(Level.Game).ScoreTeamCapture(Team, PlayerPawn(Other));
Flag(EnemyFlag).DropFrom(Flag(EnemyFlag).InitLocation);
}
return;
}

If they aren't on the same team then give the flag to them.
else
{

Give flag to enemy and let the world know about it.
BroadcastMessage(PlayerPawn(Other).PlayerReplicationInfo.PlayerName
$ " stole the enemy flag!");
bHeldItem = true;
GiveTo(Pawn(Other));
Pawn(Other).ClientMessage(PickupMessage, 'Pickup');
PlaySound (PickupSound,,2.0);
}
}
}

defaultproperties
{
PickupMessage="Got the flag!"
ItemName="Flag"
PickupViewMesh=Mesh'UnrealI.Flag1M'
}


CTF Scoring

by Dark Byte

This is the Tutorial for the CTFScoreCfg game MOD.

I would like to start by saying that what I really wanted was to create a Mutator that would work only if the game type was CTF based.

Step 1) Why it could not be a Mutator.

Here is the definition of ScoreKill as found in the mutator class:
function ScoreKill(Pawn Killer, Pawn Other)

That's a good start … now I know where I could have changed the scores but when is ScoreKill called ? I did a search in all .uc files … and it is found in many files including the CTFGame.uc file, the one that really interests me. Lets see:
Botpack\Classes\CTFGame.uc(80): BaseMutator.ScoreKill(Killer, Other);

function ScoreKill(pawn Killer, pawn Other)
{

if( (killer == Other) || (killer == None) )
Other.PlayerReplicationInfo.Score -= 1;
else if ( killer != None )
{
killer.killCount++;
if ( Killer.bIsPlayer && Other.bIsPlayer
&& (Killer.PlayerReplicationInfo.Team != Other.PlayerReplicationInfo.Team) )
Killer.PlayerReplicationInfo.Score += 1;
}
if ( bAltScoring && (Killer != Other) && (killer != None) && Other.bIsPlayer )
Other.PlayerReplicationInfo.Score -= 1;

Other.DieCount++;

BaseMutator.ScoreKill(Killer, Other);
}

That's very fine and dandy … if killer is the same as killed it's a suicide and we lose 1 point. If someone else actually killed us, he gets 1 point and 1 kill. The score is retained in the PlayerReplicationInfo. If the game is working with alternate scoring, the killee loses 1 point. Then the killee gets his Die Count increased. Ok .. that's simple … in my Mutator, all I need is to check for the same states and revert what was done here for points (I don't want to change the Kill or Die count) … then I apply my personal scoring technique. Here is what it should look like:
function ScoreKill(pawn Killer, pawn Other)
{

if ( killer != None && killer != Other )
{
// Only if both are players and not in the same team.
if ( Killer.bIsPlayer && Other.bIsPlayer
&& Killer.PlayerReplicationInfo.Team != Other.PlayerReplicationInfo.Team) )
{
// Remove the point that was awarded in CTFGame.ScoreKill()
// and add (2 times subtract) the score that was chosen
// by the server manager. Do the same for the points lost
// or given for dying.

Killer.PlayerReplicationInfo.Score -= 1 -MyKillScore;
Other.PlayerReplicationInfo.Score += MyDeathScore;
}
}

// Let the Mutator Class handle calling the next mutator.
Super.ScoreKill(Killer, Other);
}

Now I want to see if the killed person had the flag. Let find out how to tell, I would guess that the PlayerReplicationInfo has some information about that and I was right.
var Decoration HasFlag;

Here is my modified code:
function ScoreKill(pawn Killer, pawn Other)
{

if ( killer != None && killer != Other )
{
// Only if both are players and not in the same team.
if ( Killer.bIsPlayer && Other.bIsPlayer
&& Killer.PlayerReplicationInfo.Team != Other.PlayerReplicationInfo.Team) )
{
// All we care is that the dead player had the flag.
If ( Other.PlayerReplicationInfo.HasFlag )
{
// Remove the 5 points for killing the carrier and add
// the score that was chose by the server manager.
Killer.PlayerReplicationInfo.Score -= 5 -MyFlagKillScore;
Other.PlayerReplicationInfo.Score += MyFlagDeathScore;
}
else
{
// Remove the point that was awarded in CTFGame.ScoreKill()
// and add (2 times subtract) the score that was chosen
// by the server manager. Do the same for the points lost
// or given for dying.

Killer.PlayerReplicationInfo.Score -= 1 -MyKillScore;
Other.PlayerReplicationInfo.Score += MyDeathScore;
}
}
}

// Let the Mutator Class handle calling the next mutator.
Super.ScoreKill(Killer, Other);
}

Pretty simple heh … but guess what ? … It does not work. I could not understand so I digged deeper to understand what was going on. When Is the ScoreKill() function called in CTFGame.uc ? .. lets see … ah, there it is .. in GameInfo.Killed() .. it calls ScoreKill. You may wonder how I got to GameInfo ? .. lets see the structure of classes … CTFGame is derived from TeamGamePlus, which is derived from DeathMatchPlus, Which is derived from TournamentGameInfo which is derived from GameInfo. Also, lets take a look at Mutator.ScoreKill()
function ScoreKill(Pawn Killer, Pawn Other)
{
// Called by GameInfo.ScoreKill()
if ( NextMutator != None )
NextMutator.ScoreKill(Killer, Other);
}

Called by GameInfo.ScoreKill() … ok .. but where is GameInfo.ScoreKill called from ? … ok, GameInfo.Killed() …. So what does GameInfo.Killed() do ?

Since I'm interested in CTFGame .. let's see how CTFGame.Killed() is handling it.
function Killed( pawn Killer, pawn Other, name damageType )
{
local int NextTaunt, i;
local bool bAutoTaunt;

if ( Other.bIsPlayer && (Other.PlayerReplicationInfo.HasFlag != None) )
{
if ( (Killer != None) && Killer.bIsPlayer && Other.bIsPlayer &&
(Killer.PlayerReplicationInfo.Team != Other.PlayerReplicationInfo.Team) )
{
killer.PlayerReplicationInfo.Score += 4;
bAutoTaunt = ((TournamentPlayer(Killer) != None)
&& TournamentPlayer(Killer).bAutoTaunt);
if ( (Bot(Killer) != None) || bAutoTaunt )
{
NextTaunt = Rand(class<ChallengeVoicePack>
(Killer.PlayerReplicationInfo.VoiceType).Default.NumTaunts);
for ( i=0; i<4; i++ )
{
if ( NextTaunt == LastTaunt[i] )
NextTaunt = Rand(class<ChallengeVoicePack>
(Killer.PlayerReplicationInfo.VoiceType).Default.NumTaunts);
if ( i >> 0 )
LastTaunt[i-1] = LastTaunt[i];
}
LastTaunt[3] = NextTaunt;
killer.SendGlobalMessage(None, 'AUTOTAUNT', NextTaunt, 5);
}
}
CTFFlag(Other.PlayerReplicationInfo.HasFlag).Drop(0.5 * Other.Velocity);
}

Super.Killed(Killer, Other, damageType);
}

First, it gives 4 points to the flag carrier killer … killer.PlayerReplicationInfo.Score += 4;

But, wait a minute … Its telling the flag carrier to drop the flag … what is happening then ?
Holder.PlayerReplicationInfo.HasFlag = None;

Its really resetting the HasFlag property to None .. which means that when ScoreKill() is called, the carrier does not have the flag anymore … darn. There is no way I can have the correct information in a Mutator .. so I have to make it a MOD.

Step 2) Making it a MOD

Okay, now I know I have to make it a MOD. It does not please me but I have no choice. I want it to be a CTF based MOD so I will derive a new class from CTFGame.
//===============================================
// CTFScoreCfgGame.
//===============================================
class CTFScoreCfgGame expands CTFGame
config (CTFScoreCfg);

var config int RegularKillScore;
var config int FlagKillScore;
var config int RegularDeathScore;
var config int FlagDeathScore;
var config int FlagCaptureScore;
var config int FlagReturnScore;

The config extension is simply for keeping the values selected by the server manager into the CTFScoreCfg.ini file instead of UnrealTournament.ini .. this way, if one wants to get rid of CTFScoreCfg, he can delete CTFScoreCfg.* and all will be gone.

I also need some default initial values that I will use:
defaultproperties
{
GameName="CTF Configurable Scoring"
RegularKillScore=1
RegularDeathScore=0
FlagKillScore=5
FlagDeathScore=0
FlagCaptureScore=8
FlagReturnScore=0
}

I give it a new game name and put in the values that the game normally gives to players for the events. Now, instead of modifying the Mutator.ScoreKill() function, I will create my own .Killed() function where I will catch the player's flag state before the flag is dropped. Don't forget that the higher derived class gets the call first. Here is the code now.
function Killed( pawn Killer, pawn Other, name damageType )
{
// Both must be players, and not from the same team …
// check for Killer != None before checking anything else
// from killer.
if ( Other.bIsPlayer && Killer != None && Killer.bIsPlayer &&
(Killer.PlayerReplicationInfo.Team != Other.PlayerReplicationInfo.Team) )
{
if ( Other.PlayerReplicationInfo.HasFlag != None )
{
killer.PlayerReplicationInfo.Score -= 5 - FlagKillScore;
Other.PlayerReplicationInfo.Score += FlagDeathScore;
}
else
{
killer.PlayerReplicationInfo.Score -= 1 - RegularKillScore;
Other.PlayerReplicationInfo.Score += RegularDeathScore;
}

}

// Don't forget to call parent Killed Code.
Super.Killed(Killer, Other, damageType);
}

I also wanted to allow the score attributed to capturing the flag and returning the flag to change. After doing some long research, I stepped on the CTFGame.ScoreFlag() function. And as a bonus, this function is called whether the flag is Scored or Returned. Exactly what I was looking for. Here is the code I used:
function ScoreFlag(Pawn Scorer, CTFFlag theFlag)
{
if (Scorer.PlayerReplicationInfo.Team != theFlag.Team)
Scorer.PlayerReplicationInfo.Score -= 7 - FlagCaptureScore;
else
Scorer.PlayerReplicationInfo.Score += FlagReturnScore;

// Again, be graceful and call parent code
Super.ScoreFlag(Scorer, theFlag);
}

Basically, if the team of the scorer is not same as the team of the flag, this means we captured the flag. Otherwise, we just returned our own flag.

Step 3) A user interface for choosing points for each event.

A while ago, I had downloaded the EavyHunter Mod and had seen that it added a menu entry in the Mod Menu. It also features a Dialog window with which one could select some options for it. The same applied for the ReProtect mutator. I wanted to have the same kind of dialog window for my MOD. I started by extracting the code for the ReProtect mutator … and looked how they did it. Its not that hard, at least once you have an example to follow. First, lets add the Menu.
///////////////////////////////////////////////////////
// CTFScoreCfgMenuItem
///////////////////////////////////////////////////////
class CTFScoreCfgMenuItem expands UMenuModMenuItem;

function Execute()
{
MenuItem.Owner.Root.CreateWindow(class'CTFScoreCfgWindow',
10, 10, 150, 100);
}

defaultproperties
{
MenuCaption="CTF Score Configuration"
MenuHelp="Configure the points given when killing or being killed in CTF."
}

As you can see … its not very hard. But you can see that its using the CreateWindow() function with the CTFScoreCfgWindow class when the menu entry is selected. What is in this file ?
///////////////////////////////////////////////////////
// CTFScoreCfgWindow
///////////////////////////////////////////////////////
class CTFScoreCfgWindow extends UMenuFramedWindow;

function Created()
{
bSizable=False;

SetSize(350, 190);

WinLeft=(Root.WinWidth-WinWidth)/2;
WinTop=(Root.WinHeight-WinHeight)/2;

Super.Created();
}

function ResolutionChanged(float W, float H)
{
WinLeft=(Root.WinWidth-WinWidth)/2;
WinTop=(Root.WinHeight-WinHeight)/2;

Super.ResolutionChanged(W, H);
}

defaultproperties
{
ClientClass=Class'CTFScoreCfg.CTFScoreCfgClientWindow'
WindowTitle="CTF Score Configuration"
}

In Created(), we handle the initial properties of the window, like its size, and we center the window on the desktop. With ResolutionChanged() we recenter the window if the resolution is changed. The ClientClass default property is where we tell the framed window what its content will be. So again, we have to define a new window class. But a window client class this time.
///////////////////////////////////////////////////////
// CTFScoreCfgClientWindow
///////////////////////////////////////////////////////
class CTFScoreCfgClientWindow extends UMenuDialogClientWindow;

We need to define some variables. Our dialog will contain 1 push button marked as OK (I just realized I forgot to put a cancel button). We also will need 6 sliders. So lets define those needed local variables.

var UWindowSmallButton OKButton;
var UWindowHSliderControl RKSSlider;
var UWindowHSliderControl RDSSlider;
var UWindowHSliderControl FKSSlider;
var UWindowHSliderControl FDSSlider;
var UWindowHSliderControl FCSSlider;
var UWindowHSliderControl FRSSlider;

Ok .. we have our sliders and an OK button ready to put in the dialog. We also need to have some value retainers.
var int RegularKillScore;
var int RegularDeathScore;
var int FlagKillScore;
var int FlagDeathScore;
var int FlagCaptureScore;
var int FlagReturnScore;

And of course, we want our default text properties to be used. I am not sure exactly how default properties are set but it seems that the following variables automatically take the value of their default properties. My guess is that the name is very important.
var string OKHelp, OKText;
var string RKSHelp, RKSText;
var string RDSHelp, RDSText;
var string FKSHelp, FKSText;
var string FDSHelp, FDSText;
var string FCSHelp, FCSText;
var string FRSHelp, FRSText;

Now … again in the Created() function, we will initialize all our values and prepare the sliders to be useable.

For each of the sliders / values, I do the following:
RegularKillScore=class'CTFScoreCfg.CTFScoreCfgGame'.default.RegularKillScore;
RKSSlider=CreateSlider(RegularKillScore, RKSText, RKSHelp, nRow);
nRow += 20;

Get the saved value that is stored in the CTFScoreCfgGame source file. Its actually saving all this to a CTFScoreCfg.ini file (makes it easier to clean if the Mod becomes unwanted).

Then I initialize each slider and increment the placement for the next slider. For more information about initializing, check the CreateSlider() and ScoreChanged() function, they should be self explanatory.

Handling the slider changes is also easy. Just handle all in the Notify() function. The 2 parameters contain the control and the type of notification. Again, should be self explanatory as you can see:
function Notify(UWindowDialogControl C, byte E)
{
Super.Notify(C, E);

switch(E)
{
case DE_Click:
switch (C)
{
case OKButton:
Close();
break;
}
case DE_Change:
switch(C)
{
case RKSSlider:
ScoreChanged(RegularKillScore, RKSSlider, RKSText);
break;

case RDSSlider:
ScoreChanged(RegularDeathScore, RDSSlider, RDSText);
break;

case FKSSlider:
ScoreChanged(FlagKillScore, FKSSlider, FKSText);
break;

case FDSSlider:
ScoreChanged(FlagDeathScore, FDSSlider, FDSText);
break;

case FCSSlider:
ScoreChanged(FlagCaptureScore, FCSSlider, FCSText);
break;

case FRSSlider:
ScoreChanged(FlagReturnScore, FRSSlider, FRSText);
break;
}
}
}

My final word on this tutorial is that you should not be afraid to look and search in the core classes and also to seek in others code and find what they did to achieve their results. Half of the work is to study, the other half is creating.


Dispersion Pistol

by crack_addict

The Dispersion Pistol is the default weapon used in Unreal DM, and probably the first weapon you will find in Unreal SP. It has two modes of fire, both projectile based. Primary fires a energy projectile based upon the current mode of the weapon (the Dispersion Pistol can be upgraded by another item). Secondary fires a more powerful projectile based upon how long the Pawn charges.
//=================================================
// DispersionPistol.
//=================================================
class DispersionPistol expands Weapon;

Whenever you come across something that begins with "#exec", that tells the compiler to import some file. Generally the things that are imported are models/meshes, sounds, and textures...anything that you find in Unreal that Unrealed doesn't create. You do not need to use any "#exec" lines if you are not importing any new models/meshes, or if you import textures and/or sounds inside of Unrealed.

For all weapons there are 3 different models/meshes that the Unreal package uses. Player view is the model that is shown to whoever is holding the weapon. Pickup view is the model that is shown when a weapon is sitting in a level waiting to be picked up. 3rd person is the model shown to other Players when they look at a Pawn using that particular weapon.

The player view model is held up close to the Player's body, so generally it is a fraction of the size that pickup and 3rd person versions, but all 3 of the models come from the same source. All of the following pre imports first the mesh, sets the origin of the model (for rotation etc.), scales the model to the appropriate size, identifies all of the animations of the model (SEQUENCE), and then imports a texture and applies it to the mesh.
// player view version
#exec MESH IMPORT MESH=DPistol ANIVFILE=MODELS\dgun_a.3D
DATAFILE=MODELS\dgun_d.3D X=0 Y=0 Z=0

#exec MESH ORIGIN MESH=DPistol X=0 Y=0 Z=0 YAW=-64 PITCH=0
#exec MESHMAP SCALE MESHMAP=DPistol X=0.005 Y=0.005 Z=0.01
#exec MESH SEQUENCE MESH=DPistol SEQ=All STARTFRAME=0 NUMFRAMES=141
#exec MESH SEQUENCE MESH=DPistol SEQ=Select1 STARTFRAME=0 NUMFRAMES=11
GROUP=Select
#exec MESH SEQUENCE MESH=DPistol SEQ=Shoot1 STARTFRAME=11 NUMFRAMES=3
#exec MESH SEQUENCE MESH=DPistol SEQ=Idle1 STARTFRAME=14 NUMFRAMES=2
#exec MESH SEQUENCE MESH=DPistol SEQ=Down1 STARTFRAME=16 NUMFRAMES=5
#exec MESH SEQUENCE MESH=DPistol SEQ=PowerUp1 STARTFRAME=21 NUMFRAMES=4
#exec MESH SEQUENCE MESH=DPistol SEQ=Still STARTFRAME=25 NUMFRAMES=5
#exec MESH SEQUENCE MESH=DPistol SEQ=Select2 STARTFRAME=30 NUMFRAMES=11
GROUP=Select
#exec MESH SEQUENCE MESH=DPistol SEQ=Shoot2 STARTFRAME=41 NUMFRAMES=3
#exec MESH SEQUENCE MESH=DPistol SEQ=Idle2 STARTFRAME=44 NUMFRAMES=2
#exec MESH SEQUENCE MESH=DPistol SEQ=Down2 STARTFRAME=46 NUMFRAMES=5
#exec MESH SEQUENCE MESH=DPistol SEQ=PowerUp2 STARTFRAME=51 NUMFRAMES=9
#exec MESH SEQUENCE MESH=DPistol SEQ=Select3 STARTFRAME=60 NUMFRAMES=11
GROUP=Select
#exec MESH SEQUENCE MESH=DPistol SEQ=Shoot3 STARTFRAME=71 NUMFRAMES=3
#exec MESH SEQUENCE MESH=DPistol SEQ=Idle3 STARTFRAME=74 NUMFRAMES=2
#exec MESH SEQUENCE MESH=DPistol SEQ=Down3 STARTFRAME=76 NUMFRAMES=5
#exec MESH SEQUENCE MESH=DPistol SEQ=PowerUp3 STARTFRAME=81 NUMFRAMES=9
#exec MESH SEQUENCE MESH=DPistol SEQ=Select4 STARTFRAME=90 NUMFRAMES=11
GROUP=Select
#exec MESH SEQUENCE MESH=DPistol SEQ=Shoot4 STARTFRAME=101 NUMFRAMES=3
#exec MESH SEQUENCE MESH=DPistol SEQ=Idle4 STARTFRAME=104 NUMFRAMES=2
#exec MESH SEQUENCE MESH=DPistol SEQ=Down4 STARTFRAME=106 NUMFRAMES=5
#exec MESH SEQUENCE MESH=DPistol SEQ=PowerUp4 STARTFRAME=111 NUMFRAMES=9
#exec MESH SEQUENCE MESH=DPistol SEQ=Select5 STARTFRAME=120 NUMFRAMES=11
GROUP=Select
#exec MESH SEQUENCE MESH=DPistol SEQ=Shoot5 STARTFRAME=131 NUMFRAMES=3
#exec MESH SEQUENCE MESH=DPistol SEQ=Idle5 STARTFRAME=134 NUMFRAMES=2
#exec MESH SEQUENCE MESH=DPistol SEQ=Down5 STARTFRAME=136 NUMFRAMES=5

#exec TEXTURE IMPORT NAME=DPistol1 FILE=MODELS\dgun.PCX GROUP="Skins"
#exec OBJ LOAD FILE=Textures\SmokeEffect2.utx PACKAGE=UNREALI.SEffect2
#exec MESHMAP SETTEXTURE MESHMAP=DPistol NUM=1 TEXTURE=DPistol1
#exec MESHMAP SETTEXTURE MESHMAP=DPistol NUM=0
TEXTURE=Unreali.SEffect2.SmokeEffect2

// pickup version
#exec MESH IMPORT MESH=DPistolPick ANIVFILE=MODELS\dgunlo_a.3D
DATAFILE=MODELS\dgunlo_d.3D X=0 Y=0 Z=0

#exec MESH ORIGIN MESH=DPistolPick X=0 Y=0 Z=0 YAW=64
#exec MESH SEQUENCE MESH=DPistolPick SEQ=All STARTFRAME=0 NUMFRAMES=1
#exec TEXTURE IMPORT NAME=DPistol1 FILE=MODELS\dgun.PCX GROUP="Skins"
#exec MESHMAP SCALE MESHMAP=DPistolPick X=0.04 Y=0.04 Z=0.08
#exec MESHMAP SETTEXTURE MESHMAP=DPistolPick NUM=1 TEXTURE=DPistol1

// 3rd person perspective version
#exec MESH IMPORT MESH=DPistol3rd ANIVFILE=MODELS\dgunlo_a.3D
DATAFILE=MODELS\dgunlo_d.3D X=0 Y=0 Z=0

#exec MESH ORIGIN MESH=DPistol3rd X=0 Y=-200 Z=-110 YAW=-64 ROLL=9
#exec MESH SEQUENCE MESH=DPistol3rd SEQ=All STARTFRAME=0 NUMFRAMES=6
#exec MESH SEQUENCE MESH=DPistol3rd SEQ=Still STARTFRAME=0 NUMFRAMES=1
#exec MESH SEQUENCE MESH=DPistol3rd SEQ=Shoot1 STARTFRAME=0 NUMFRAMES=6
#exec TEXTURE IMPORT NAME=DPistol1 FILE=MODELS\dgun.PCX GROUP="Skins"
#exec MESHMAP SCALE MESHMAP=DPistol3rd X=0.025 Y=0.025 Z=0.05
#exec MESHMAP SETTEXTURE MESHMAP=DPistol3rd NUM=1 TEXTURE=DPistol1

Here "#exec" is used to import in sounds for the weapon, one for charging, another for firing, and another for when a Pawn picks it up.
#exec AUDIO IMPORT FILE="Sounds\dispersion\Powerup3.WAV" NAME="PowerUp3"
GROUP="Dispersion"
#exec AUDIO IMPORT FILE="Sounds\dispersion\DShot1.WAV" NAME="DispShot"
GROUP="Dispersion"
#exec AUDIO IMPORT FILE="Sounds\dispersion\Dpickup2.WAV" NAME="DispPickup"
GROUP="Dispersion"

Here after all the "#exec" lines the global variables are defined. These variables stay alive as long as their is a Spawned copy of this particular class in the game, whereas the variables defined inside of functions later on are local, and die as soon as the function is finished. Powerlevel stores what level of upgrade this particular Dispersion Pistol is, WeaponPos is an extra vector that is used later on to keep track of the current position of the weapon. Count and ChargeSize are both used to calculate the amount of charge when the Pistol is fired in Secondary mode. cl1 and cl2 are instances of ChargeLight, that as far as I can tell aren't used for anything useful in this version of the pre. Amp is a copy used to determine/use the inventory Amplifier, if the Pawn has an active version. PowerUpSound is the power up sound (tough one eh?).
var travel int PowerLevel;
var vector WeaponPos;
var float Count,ChargeSize;
var ChargeLight cl1,cl2;
var Pickup Amp;
var Sound PowerUpSound;

The Engine calls three functions whenever an Actor is created, PreBeginPlay(), BeginPlay(), and PostBeginPlay(). They are very useful for executing pre no matter what, every time an instance of this Actor is created. Here PostBeginPlay() is used to store what Projectile to fire for both Primary and Secondary Fire.
function PostBeginPlay()
{
Super.PostBeginPlay();
ProjectileClass = class'DispersionAmmo';
AltProjectileClass = class'DispersionAmmo';
ProjectileSpeed = class'DispersionAmmo'.Default.speed;
AltProjectileSpeed = class'DispersionAmmo'.Default.speed;
}

RateSelf() is an AI function used solely by Bots (at the moment) to determine what priority this weapon should take when compared to others in the Bot's inventory.
function float RateSelf( out int bUseAltMode )
{
local float rating;

if ( Pawn(Owner).bShootSpecial )
return 1000;

if ( Amp != None )
rating = 3.1 * AIRating;
else
rating = AIRating;

if ( AmmoType.AmmoAmount <=0 )
return 0.05;
if ( pawn(owner).enemy == none )
{
busealtmode = 0;
return rating * (powerlevel + 1);
}

busealtmode = int( frand() < 0.3 );
return rating * (powerlevel + 1);
}

SuggestAttackStyle() determines whether the bot should go with primary or secondary fire.
// return delta to combat style
function float SuggestAttackStyle()
{
local float EnemyDist;
local Inventory Inv;

if ( !Pawn(Owner).bIsPlayer || (PowerLevel > 0) )
return 0;

return -0.3;
}

HandlePickupQuery() is a great function that allows an inventory item to perform some action whenever its Owner picks up another item. The Dispersion Pistol uses it here to check if its Owner just picked up a Powerup, and if so it will 'upgrade' itself.
function bool HandlePickupQuery( inventory Item )
{
if ( Item.IsA('WeaponPowerup') )
{
AmmoType.AddAmmo(AmmoType.MaxAmmo);
Pawn(Owner).ClientMessage(Item.PickupMessage);
Item.PlaySound (PickupSound);
if ( PowerLevel<4 )
{
shakevert = default.shakevert + powerlevel;
powerupsound = item.activatesound;
if ( pawn(owner).weapon == self )
{
powerlevel++;
gotostate('powerup');
}
else if ( (pawn(owner).weapon != self)
&& !pawn(owner).bneverswitchonpickup )
{
pawn(owner).weapon.putdown();
pawn(owner).pendingweapon = self;
gotostate('powerup', 'waiting');
}
else powerlevel++;
}
item.setrespawn();
return true;
}
else
return Super.handlepickupquery(item);
}

SetSwitchPriority() is a function used to automatically determine what weapon should come up when you either pick up a new weapon, or run out of ammo for the current weapon.
function SetSwitchPriority(pawn Other)
{
local int i;
local name MyType;

if (PowerLevel == 0)
MyType = 'DispersionPistol';
else if (PowerLevel == 1)
MyType = 'DispersionPower1';
else if (PowerLevel == 2)
MyType = 'DispersionPower2';
else if (PowerLevel == 3)
MyType = 'DispersionPower3';
else if (PowerLevel == 4)
MyType = 'DispersionPower4';
else
MyType = 'DispersionPower5';

if ( PlayerPawn(Other) != None )
for ( i=0; i<20; i++)
if ( playerpawn(other).weaponpriority[i] == mytype )
{
autoswitchpriority = i;
return;
}
}

function becomepickup()
{
amp = none;
super.becomepickup();
}

PlayFiring() (and PlayAltFiring()) are basically the animation and sound control functions that are called whenever the weapon is fired. The Dispersion Pistol plays a firing sound, shakes it's Owner's view via ShakeView(), and then based upon the PowerLevel it plays a firing animation.
function PlayFiring()
{
AmmoType.GoToState('Idle2');
Owner.PlaySound(AltFireSound, SLOT_None, 1.8*Pawn(Owner).SoundDampening
,,,1.2);
if ( PlayerPawn(Owner) != None )
PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
if (PowerLevel==0)
PlayAnim('Shoot1',0.4,0.2);
else if (PowerLevel==1)
PlayAnim('Shoot2',0.3,0.2);
else if (PowerLevel==2)
PlayAnim('Shoot3',0.2, 0.2);
else if (PowerLevel==3)
PlayAnim('Shoot4',0.1,0.2);
else if (PowerLevel==4)
PlayAnim('Shoot5',0.1,0.2);
}

ProjectileFire() is the function used by all Projectile-based weapons to fire the appropriate projectile, in the appropriate direction, from the correct starting point.
function Projectile ProjectileFire(class ProjClass, float ProjSpeed, bool bWarn)
{
local Vector Start, X,Y,Z;
local DispersionAmmo da;
local float Mult;

Owner.MakeNoise(Pawn(Owner).SoundDampening);

If the Pistol's Owner has an Amplifier then set the damage multiplier equal to whatever Amp.UseCharge(80) returns.
if (Amp!=None) Mult = Amp.UseCharge(80);
else Mult=1.0;

GetAxes is a function that returns normals along the axis of a given rotator. Here is used to store the axes from the Pistol's Owner's ViewRotation (the direction the Owner is looking).
GetAxes(Pawn(owner).ViewRotation,X,Y,Z);

Start is calculated by first using the Owner's Location, then adding ClacDrawOffset(), and then moving along the proper axis the amount determined by FireOffset specified in the Default Properties.
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X +
FireOffset.Y * Y + FireOffset.Z * Z;

AdjustedAim is essentially the direction that the projectile is to be fired. It is calculated here by a function in Pawn called AdjustAim, that essentially just uses the Owner's ViewRotation and adjusts it towards any targets if AutoAim is enabled.
AdjustedAim = pawn(owner).AdjustAim(ProjSpeed, Start,
AimError, True, (3.5*FRand()-1<PowerLevel));

Here is where the actual sparkling projectile you see is created. Depending on the Powerlevel, different projectiles (with different properties/meshes) are created.
if ( (PowerLevel == 0) || (AmmoType.AmmoAmount < 10) )
da = dispersionammo(spawn(projclass,,, start,adjustedaim));
else
{
if ( (powerlevel==1) && ammotype.useammo(2) )
da = spawn(class'dammo2',,, start,adjustedaim);
if ( (powerlevel==2) && ammotype.useammo(4) )
da = spawn(class'dammo3',,, start,adjustedaim);
if ( (powerlevel==3) && ammotype.useammo(5) )
da = spawn(class'dammo4',,, start ,adjustedaim);
if ( (powerlevel>=4) && AmmoType.UseAmmo(6) )
da = Spawn(class'DAmmo5',,, Start,AdjustedAim);
}

if ( da != None )
{
if (Mult>1.0) da.InitSplash(FMin(da.damage * Mult, 100));
}
}

Fire() and AltFire() are one of the many functions called when a Pawn decides it wants to fire the weapon its using. This version of AltFire() just sets a boolean to true for AI purposes, calls CheckVisibility() which I'm not exactly sure does, and then goes to the AltFiring state.
function AltFire( float Value )
{
bPointing=True;
CheckVisibility();
GoToState('AltFiring');
}

The AltFiring state in the Dispersion Pistol doesn't actually fire the weapon, but instead increments a value while the AltFire is pushed and once the button is released it changes states to ShootLoad which takes care of firing the projectile.
state AltFiring
{
ignores AltFire;

The Tick() function is a way to make rapid updates/changes to a class. It is called whenever possible (when enabled), and can be used for pretty much anything you can think of. Be wary of putting too much pre in the tick function, because it is called alot in a short amount of time, and can bring the game to a halt if it has to process too much. The Dispersion Pistol uses it to keep track of how long it has been charging, and limits how much you can charge.
function Tick( float DeltaTime )
{
if ( Level.NetMode == NM_StandAlone )
{
PlayerViewOffset.X = WeaponPos.X + FRand()*ChargeSize*7;
PlayerViewOffset.Y = WeaponPos.Y + FRand()*ChargeSize*7;
PlayerViewOffset.Z = WeaponPos.Z + FRand()*ChargeSize*7;
}
ChargeSize += DeltaTime;
if( (pawn(Owner).bAltFire==0)) GoToState('ShootLoad');
Count += DeltaTime;
if (Count > 0.3)
{
Count = 0.0;
If (!AmmoType.UseAmmo(1)) GoToState('ShootLoad');
AmmoType.GoToState('Idle2');
}
}

EndState() and BeginState() are two function that can be used to do something at the end and beginning of a state respectively. Dispersion Pistol uses BeginState() to initialize two variables, and uses EndState() to clean up.
Function EndState()
{
PlayerviewOffset = WeaponPos;
if (cl1!=None) cl1.Destroy();
if (cl2!=None) cl2.Destroy();
}

function BeginState()
{
WeaponPos = PlayerviewOffset;
ChargeSize=0.0;
}

The Begin: and End: labels are nearly identical to BeginState() and EndState(), the only main difference being that BeginState() and EndState() are functions, and if you need to use a local variable (to find some object for example) you can only create variables inside functions. Otherwise Begin: and End: can be used for the same purposes.
Begin:
if (AmmoType.UseAmmo(1))
{
Owner.Playsound(Misc1Sound,SLOT_Misc, Pawn(Owner).SoundDampening*4.0);
Count = 0.0;
Sleep(2.0 + 0.6 * PowerLevel);
GoToState('ShootLoad');
}
else GotoState('Idle');
}

ShootLoad is used to fire off a projectile when the Dispersion has either reached its max charge, or the Owner decided to let go. Nothing really special in here, the BeginState() function is essentially ProjectileFire() except that it takes into account the ChargeSize variable, to increase damage and size appropriately.

state ShootLoad
{
  function Fire(float F) {}
  function AltFire(float F) {}

  function BeginState()
  {
    local DispersionAmmo d;
    local Vector Start, X,Y,Z;
    local float Mult;

    if (Amp!=None) Mult = Amp.UseCharge(ChargeSize*50+50);
    else Mult=1.0;

    Owner.MakeNoise(Pawn(Owner).SoundDampening);
    GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
    InvCalcView();
    Start = Location + FireOffset.X * X + FireOffset.Y * Y
            + FireOffset.Z * Z;
    AdjustedAim = pawn(owner).AdjustAim(AltProjectileSpeed,
                       Start, AimError, True, True);
    d = DispersionAmmo(Spawn(AltProjectileClass,,, Start,AdjustedAim));
    d.bAltFire = True;
    d.DrawScale = 0.5 + ChargeSize*0.6;
    d.InitSplash(d.DrawScale * Mult * 1.1);
    Owner.PlaySound(AltFireSound, SLOT_Misc, 1.8*Pawn(Owner).SoundDampening);
    if ( PlayerPawn(Owner) != None )
      PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag*ChargeSize, ShakeVert);
    if (PowerLevel==0) PlayAnim('Shoot1',0.2, 0.05);
    else if (PowerLevel==1) PlayAnim('Shoot2',0.2, 0.05);
    else if (PowerLevel==2) PlayAnim('Shoot3',0.2, 0.05);
    else if (PowerLevel==3) PlayAnim('Shoot4',0.2, 0.05);
    else if (PowerLevel==4) PlayAnim('Shoot5',0.2, 0.05);
  }
Begin:
  FinishAnim();
  Finish();
}

PlayIdleAnim() is an animation function that is called to play an idle animation, and because the Dispersion Pistol happens to have more than one idle animation, PlayIdleAnim() plays the proper animation depending on the PowerLevel.

function PlayIdleAnim()
{
  if (PowerLevel==0) LoopAnim('Idle1',0.04,0.2);
  else if (PowerLevel==1) LoopAnim('Idle2',0.04,0.2);
  else if (PowerLevel==2) LoopAnim('Idle3',0.04,0.2);
  else if (PowerLevel==3) LoopAnim('Idle4',0.04,0.2);
  else if (PowerLevel==4) LoopAnim('Idle5',0.04,0.2);
}

The PowerUp state is active when the weapon is powering up after picking up a weaponpowerup (tough one eh?), and can be used to play animations, sounds, modify variables or anything else. The Dispersion Pistol needs this to play the proper animation (remember those cool things popping out of your gun?), and modify the ammo.

state PowerUp
{
ignores fire, altfire;

  function BringUp()
  {
    bWeaponUp = false;
    PlaySelect();
    GotoState('Powerup', 'Raising');
  }

  function bool PutDown()
  {
    bChangeWeapon = true;
    return True;
  }

  function BeginState()
  {
    bChangeWeapon = false;
  }

Raising:
  FinishAnim();
  PowerLevel++;
Begin:
  if (PowerLevel<5)
  {
    ammotype.maxammo += 10;
    ammotype.addammo(10);
    if ( powerlevel < 5 )
      owner.playsound(powerupsound, slot_none, pawn(owner).sounddampening);
    if (powerlevel==1)
      playanim('powerup1',0.1, 0.05);
    else if (powerlevel==2)
      playanim('powerup2',0.1, 0.05);
    else if (powerlevel==3)
      playanim('powerup3',0.1, 0.05);
    else if (powerlevel==4)
      playanim('powerup4',0.1, 0.05);
    finishanim();
    if ( bchangeweapon )
      gotostate('downweapon');
    finish();
  }
waiting:
}

All Tween* functions are animation related functions that are used to make the transition between different animations. It is important to note that TweenAnim is not the same as PlayAnim. You should use PlayAnim when there isn't currently an animation already playing, and use TweenAnim when one is playing, otherwise you could end up with noticeable "jumps" from one animation to the other.
function TweenDown()
{
if ( GetAnimGroup(AnimSequence) == 'Select' )
TweenAnim( AnimSequence, AnimFrame * 0.4 );
else
{
if (PowerLevel==0) PlayAnim('Down1', 1.0, 0.05);
else if (PowerLevel==1) PlayAnim('Down2', 1.0, 0.05);
else if (PowerLevel==2) PlayAnim('Down3', 1.0, 0.05);
else if (PowerLevel==3) PlayAnim('Down4', 1.0, 0.05);
else if (PowerLevel==4) PlayAnim('Down5', 1.0, 0.05);
}
}

function TweenSelect()
{
TweenAnim('Select1',0.001);
}

function PlaySelect()
{
Owner.PlaySound(SelectSound, SLOT_None, Pawn(Owner).SoundDampening);
if (PowerLevel==0) PlayAnim('Select1',0.5,0.0);
else if (PowerLevel==1) PlayAnim('Select2',0.5,0.0);
else if (PowerLevel==2) PlayAnim('Select3',0.5,0.0);
else if (PowerLevel==3) PlayAnim('Select4',0.5,0.0);
else if (PowerLevel==4) PlayAnim('Select5',0.5,0.0);
}


Drawing Health and Armour as Vertical Bars

by The Apeman

Bokkelstra@Hotmail.com

Someone asked how to do this in the Coding area of the BeyondUnreal forums, and I decided that it might be nice to have a tutorial on this subject. If you're that person, I took the liberty of changing your idea a bit, but you should be able to understand what to do. I assume that you already have UClasses (or some other way to compile your code outside of UnrealEd) up and running. You won't be able to follow this tutorial precisely if you don't use "UCC -make" to compile your code, as you'll be importing some graphics as well. (If you're not sure what UCC is, it generally means you're not using UnrealEd) I also assume that you have a basic understanding of the C++ like syntax unrealscript uses.

What I'll be explaining here is how to remove the status doll and health+armour readouts in the top left corner of the screen, and how to replace them with two neat, easily readable bars. We'll be subclassing the ChallengeHUD for this, so we'll need to make a new game-type to show the new HUD.

If you have it, you should fire up UClasses, and make a class below ChallengeHUD. To do this, you should expand Actor, then HUD, then right-click on ChallengeHUD and below "Add edit remove", choose "Create new class below ChallengeHUD". In Classname, fill in something like "HUDwithHPbars" or something. Come up with a name. : ) You should also make up a name for your package, just call it "BarsTutorial" (the name I'll refer to in this tutorial from no on) or whatever, as long as the name doesn't already exist. Well, there's your new HUD class. Double click on it to open it up in a text-editor.

It doesn't have any code in there, so right now it'd act just like a normal HUD.

If you made this class without UClasses, you should make it look like this:
class HUDwithHPbars expands ChallengeHUD;

defaultproperties
{
}

Luckily, our HUDs parent class, ChallengeHUD, is very organized, so all the code that draws the players status in the top-left corner is contained in one function. By overriding that function in our new class, we'll make sure it isn't drawn. So, between the class defenition ( class X expands Y; ) and the default properties, you should put
simulated function DrawStatus(Canvas Canvas)
{
}

Now, our new HUD has his own DrawStatus function, so it won't be using it's parent's. Before we go and start drawing the bars in the place of the status doll, we'll need to import the graphics for the bar. To import something, you have to use an "exec" command. Ours will look like this:

#exec TEXTURE IMPORT NAME=TwoBars FILE=Textures\Bars.pcx MIPS=OFF

This will tell the compiler to add Bars.pcx (located in our packages directory, in a subdirectoty called "Textures") to our new package. If you want to find out more about exec commands, there's a good document about them in the tutorials section of www.Unrealscript.com, the site this tutorial is probably situated as well. Now you'll probably want to download the Bars.pcx I made. If you decide to remake it yourself, put everything in the same place as in the original, because this tutorial counts on it. After you've downloaded Bars.pcx, and maybe remade it, find the directory with the same name as your package in the Unreal Tournament directory. It should already have a subdirectory "Classes", now make another directory there named "Textures" and put the .pcx in there.

Now, we'll need to put the code up there that will display the bars on-screen. We'll just put our code in the DrawStatus function, since we're sure it's called and it's unused now anyway. We'll first draw the holders, like so:
simulated function DrawStatus(Canvas Canvas)
{
if ( !bHideStatus ) // we wouldn't want our bars to show up if the player doesn't want them
{
Canvas.Style = ERenderStyle.STY_Normal; // So you won't be able to see through the bars
Canvas.SetPos(Canvas.ClipX - 32, 0); // The first thing to do is setting drawing offset at the right place,
// and since the placeholder graphic is 32 pixels wide, we want it to be 32 pixels from the right side of the screen (ClipX)
Canvas.DrawTile(Texture'BarsTutorial.TwoBars', 32, 144, 32, 0, 32.0, 144.0);
Canvas.SetPos(Canvas.ClipX - 64, 0); // 32 pixels more to the right.
Canvas.DrawTile(Texture'BarsTutorial.TwoBars', 32, 144, 32, 0, 32.0, 144.0);
}
}

This is what it's all about. Drawtile is what you use most of the time to put things on the HUD.

The first argument reads Texture'Tutorial.TwoBars'. This is the texture we're using, and the one exec'll import. The second and third are 32,144. These are the dimensions the tile will be on the screen. The fourth and fifth are 32,0. This is the top left corner of the tile in the used texture (here: TwoBars, which is the name we gave to Bars.pcx). The sixth and seventh are the dimensions of the tile in the graphic. Just for ease, the second and third are the same as this, but if they were different, the graphic would be resized on the fly.

Now, we'd want to test out this HUD, but we'll need to create a new gametype for that. Just subclass DeathMatchPlus, name it DeathMatchPlusBars and have it look like this:
class DeathMatchPlusBars expands DeathMatchPlus;

defaultproperties
{
HUDType=Class'BarsTutorial.HUDwithHPbars' // this is the HUD we've made!
GameName="Just a HUD test"
}

This should pretty much work when you compile it. Put the .int file that came with the .pcx file in your system directory, modify it to match your package name, compile your package with UClasses and try it out! (select the "Just a HUD test" from the games list) The bars' placeholders should show up, but the actual bars are nowhere to be seen yet. Adding them is easy, and is quite the same procedure as drawing the placeholders. Below is all the code your class should contain. (Including the class defenition and the importing #exec function)
class HUDwithHPbars expands ChallengeHUD;

#exec TEXTURE IMPORT NAME=TwoBars FILE=Textures\Bars.pcx MIPS=OFF

simulated function DrawStatus(Canvas Canvas)
{
local TournamentPlayer POwner;
local int ArmorAmount,CurAbs,i;
local inventory Inv,BestArmor;

POwner = TournamentPlayer(Owner); // We need to make sure we're dealing with a player here, because not all Owners have health

// The following code (until !bhidestatus) was copied from ChallengeHUD, and figures out how much armour the player has
// It isn't complicated at all, but it isn't really important for this tutorial.
for( Inv=POwner.Inventory; Inv!=None; Inv=Inv.Inventory )
{
if (Inv.bIsAnArmor)
{
ArmorAmount += Inv.Charge;
}
else
{
i++;
if ( i > 100 )
break; // can occasionally get temporary loops in netplay
}
}

if ( !bHideStatus ) // we wouldn't want our bars to show up if the player doesn't want them
{
Canvas.Style = ERenderStyle.STY_Normal; // So you won't be able to see through the bars
Canvas.SetPos(Canvas.ClipX - 32, 0); // The first thing to do is setting drawing offset at the right place,
// and since the placeholder graphic is 32 pixels wide, we want it to be 32 pixels from the right side of the screen (ClipX)
Canvas.DrawTile(Texture'BarsTutorial.TwoBars', 32, 144, 32, 0, 32.0, 144.0);
Canvas.SetPos(Canvas.ClipX - 64, 0); // 32 pixels more to the right.
Canvas.DrawTile(Texture'BarsTutorial.TwoBars', 32, 144, 32, 0, 32.0, 144.0);

// Let's add the bars themselves now.
Canvas.SetPos(Canvas.ClipX - 32 + 16, 8); // We want the bars to show up 16 pixels to the right and 8 pixels down on the
// placeholders
Canvas.DrawTile(Texture'BarsTutorial.TwoBars', 8, 128*POwner.Health/200, 16, 0, 16.0, 128.0);
Canvas.SetPos(Canvas.ClipX - 64 + 16, 8);
Canvas.DrawTile(Texture'BarsTutorial.TwoBars', 8, 128*ArmorAmount/150, 0, 0, 16.0, 128.0);
}
}

defaultproperties
{
}

With everything I told you, you should be able to understand everything of the above. You should expiriment a bit with the code, try to make the bars start at the bottom of the placeholder for example. If you feel confident, you could even try to scale the bars up a bit, according to the resolution, keeping in mind that the resolution is kept in Canvas.ClipX and Canvas.ClipY, that the second and third arguments of Canvas.DrawTile are the size of the tile on-screen and that the bars look good already on low resolutions. Checking out the code of the original ChallengeHUD's DrawStatus function should give you enough information to allow the player to resize the bars, and there are bound to be more ways to improve the code above.

If you have suggestions or find a bad error in this tutorial, you can mail me at Bokkelstra@Hotmail.com (Yes, I know it's a weird E-mail adress, I just registered it in order to keep stuff apart)
This .zip file contains the texture & .int file necessary to use the example code in the tutorial.

G'luck on your further coding, and farewell!
-The Apeman


New Page 1

#exec commands

by mr. self-destruct

mr. self-destruct

Before we get started, thanks to c0mp1le, Ob1-Kenobi & Mr.Mitchell for their invaluable advice during the creation of this tutorial.

#exec commands are used to import resources (e.g. models, textures, sounds, etc.) into a .u file, the resource can be in the relevant Unreal format (e.g. utx, uax) or in one of a number of other formats that UCC and UnrealEd support.
#exec commands can either be placed in the body of a UnrealScript class or typed directly into the UnrealEd console.

Miscellaneous Resources

#exec OBJ LOAD
This #exec command will import a pre-existing Unreal resource, commonly a .utx file.

Parameter | Description | Possible values | Optional?
FILE | specifies the path of the resource to import |  |
PACKAGE | specifies the name of the package to import resource into |  |

Example:
#exec OBJ LOAD FILE=..\Textures\JWSKy.utx PACKAGE=SE

#exec TEXTURE IMPORT
Imports a texture from a .pcx file.

Parameter | Description | Possible values | Optional?
NAME | specifies the name of the texture in Unreal |  |
FILE | specifies the path of the texture to import |  |
GROUP | which group in the current package to place the texture |  | Yes
MIPS | whether or not mip-maps should be generated for this texture, should be OFF for textures that'll be used by UWindows (e.g. new HUD icons) | ON/OFF | Yes
FLAGS | 2 = masked texture |  | Yes

Example:
#exec TEXTURE IMPORT NAME=Light FILE=Textures\Light.PCX GROUP="Icons" MIPS=OFF FLAGS=2

#exec FONT IMPORT
Import a font texture for use as a font in Unreal.

Parameter | Description | Possible values | Optional?
FILE | specifies the path of the font texture to import |  |
NAME | specifies the name of the font in Unreal |  |

Example:
#exec FONT IMPORT FILE=Textures\MedFont.pcx NAME=MedFont

#exec NEW TRUETYPEFONTFACTORY
Import a true type font for use as a font in Unreal. For a thorough explanation of the nuances of importing true type fonts read this.

Parameter | Description | Possible values | Optional?
PACKAGE | specifies the name of the UTX package to import the font into (but only if importing from within UnrealEd) |  | Yes
NAME | specifies the name of the font in Unreal |  |
FONTNAME | specifies the Windows name of the font to be imported, e.g. "Arial" |  |
HEIGHT | height of the font in pixels, which is passed to the Windows' CreateFont() API call |  |
ANTIALIAS | whether or not to anti-alias the font when importing it (1 = anti-aliased) | 0/1 |
CHARACTERSPERPAGE | specifies the number of characters per 256x256 pixel font texture. The default is 64 |  | Yes
XPAD | adds horizontal space between characters |  | Yes
YPAD | adds vertical space between characters |  | Yes

Example:
#exec NEW TRUETYPEFONTFACTORY NAME=Tahoma30 FONTNAME="Tahoma" Height=30 ANTIALIAS=1 CHARACTERSPERPAGE=32

#exec AUDIO IMPORT
Import a sound from a .wav file.

Parameter | Description | Possible values | Optional?
FILE | specifies the path of the sound to import |  |
NAME | specifies the name of the sound in Unreal |  |
GROUP | which group in the current package to place the sound |  | Yes

Example:
#exec AUDIO IMPORT FILE="Sounds\ChainSaw\ChainIdle.WAV" NAME="ChainIdle" GROUP="ChainSaw"

Vertex Animation

Importing models into Unreal requires an understanding of the LOD system, read up on it here.

#exec MESH LODPARAMS
Configure various LOD options for a mesh (vertex or skeletal).

Parameter | Description | Possible values | Optional?
MESH | specifies the mesh to configure LODing for |  |
STRENGTH | per-mesh linear LOD scaler, default = 1.0, higher values result in more aggressive LOD-culling |  |
MINVERTS | the minimum number of vertices you want your mesh to always retain at the farthest distances |  | Yes
MORPH | the proportion of vertices that are allowed to contribute to the smooth morphing, 0.0 for no morphing | 0 - 1 | Yes
ZDISP | specifies in UUs the distance at which the LOD culling kicks in |  | Yes

Example:
#exec MESH LODPARAMS MESH=LodMesh STRENGTH=1.0 MINVERTS=14 MORPH=0.25 ZDISP=90.0

#exec MESH IMPORT
Imports a vertex mesh (_d.3d).

Parameter | Description | Possible values | Optional?
MESH | specifies the name of the mesh in Unreal |  |
ANIVFILE | specifies the path of the animation file |  |
DATAFILE | specifies the path of the vertex mesh |  |
X, Y, Z | set the origin of the mesh |  | Yes
MLOD | whether or not this mesh should be LODed | 0/1 | Yes
LODSTYLE | bit field with switches to change the style of building the pre-collapse sequence | 1, 2, 4, 8, 16 | Yes
LODFRAME | specify which animation frame rather than the default 0th frame to be sampled for generating the collapse sequence |  | Yes
LODNOTEX | causes texture coordinates to be ignored when importing |  | Yes
LODOLD | maintain the original order of animation vertices as they are imported |  | Yes

Example:
#exec MESH IMPORT MESH=Duke ANIVFILE=MODELS\Duke_a.3d DATAFILE=MODELS\Duke_d.3d X=0 Y=0 Z=0 LODSTYLE=1

#exec MESH ORIGIN
Sets the origin of a mesh.

Parameter | Description | Possible values | Optional?
MESH | specifies the mesh to set the origin of |  |
X, Y, Z | set the origin of the mesh |  | Yes
YAW, ROLL, PITCH | set the rotation of the mesh |  | Yes

Example:
#exec MESH ORIGIN MESH=Duke X=0 Y=0 Z=0

#exec MESH SEQUENCE
Define an animation sequence.

Parameter | Description | Possible values | Optional?
MESH | specifies the mesh to create an animation sequence for |  |
SEQ | specifies the name of the animation sequence |  |
STARTFRAME | specifies the frame at which the animation sequence starts |  |
NUMFRAMES | specifies the number of frames in the animation |  |
RATE | frames per second (though the duration of the anim is set in PlayAnim() calls) |  | Yes
GROUP | which group to place the anim in |  | Yes

Example:
#exec MESH SEQUENCE MESH=Duke SEQ=All STARTFRAME=0 NUMFRAMES=265

#exec MESH NOTIFY
Create a notifcation callback.

Parameter | Description | Possible values | Optional?
MESH | the mesh to link the notification to |  |
SEQ | specifies the name of the animation sequence |  |
TIME | call the notify function after this fraction of the animation has played (e.g. 0.1 = 1/10th) | 0 - 1 |
FUNCTION | specifies the name of the function to call |  |

Example:
#exec MESH NOTIFY MESH=Duke SEQ=All TIME=0.1 FUNCTION=LandThump

#exec MESHMAP NEW
Define a meshmap to apply textures to a mesh.

Parameter | Description | Possible values | Optional?
MESHMAP | specifies the name of the meshmap |  |
MESH | specifies the mesh which the meshmap applies to |  |

Example:
#exec MESHMAP NEW MESHMAP=Duke MESH=Duke

#exce MESHMAP SCALE
Change the scale of a meshmap.

Parameter | Description | Possible values | Optional?
MESHMAP | specifies the meshmap to scale |  |
X, Y, Z | how much to scale the meshmap on each axes |  |

Example:
#exec MESHMAP SCALE MESHMAP=Duke X=0.1 Y=0.1 Z=0.2

#exce MESHMAP SETTEXTURE
Assign a texture to part of a meshmap.

Parameter | Description | Possible values | Optional?
MESHMAP | specifies the meshmap to assign textures to |  |
NUM | where to place this texture in the MultiSkins array |  |
TEXTURE | specifies the name of the texture to apply, this texture should already have been imported |  |

Example:
#exec MESHMAP SETTEXTURE MESHMAP=Duke NUM=0 TEXTURE=Duke0

Skeletal Animation

Essential reading for the skeletal animation system can be found here.

#exec MESH MODELIMPORT
Imports a skeletal mesh (.psk).

Parameter | Description | Possible values | Optional?
MESH | specifies the name of the mesh in Unreal |  |
MODELFILE | specifies the path of the model to import |  |
X, Y, Z | set the origin of the mesh |  | Yes
MLOD | whether or not this mesh should be LODed | 0/1 | Yes
LODSTYLE | bit field with switches to change the style of building the pre-collapse sequence | 1, 2, 4, 8, 16 | Yes
LODFRAME | specify which animation frame rather than the default 0th frame to be sampled for generating the collapse sequence |  | Yes
LODNOTEX | causes texture coordinates to be ignored when importing |  | Yes
LODOLD | maintain the original order of animation vertices as they are imported |  | Yes

Example:
#exec MESH MODELIMPORT MESH=Tosc MODELFILE=MODELS\Tosc.psK LODSTYLE=8 X=0 Y=0 Z=0

#exec ANIM IMPORT
Import an animation file (.psa).

Parameter | Description | Possible values | Optional?
ANIM | specifies the name of the UAnimation object |  |
ANIMFILE | specifies the path of the animation file to import |  |
IMPORTSEQS | 1 signifies that the animation sequence info embedded into the binary .PSA file by the Max exporter is to be used |  |
MAXKEYS | sets an adjustable squeeze on the number of keys in the animation as a whole |  | Yes
COMPRESS | does the same as MAXKEYS, does the same but with a simple factor ranging from 0 to 1 | 0 - 1 | Yes

Example:
#exec ANIM IMPORT ANIM=SkAnimTest ANIMFILE=models\10.psa IMPORTSEQS=1 COMPRESS=0.9 MAXKEYS=9999999

#exec ANIM SEQUENCE
Import an animation sequence.

Parameter | Description | Possible values | Optional?
ANIM | specifies the name of the animation |  |
SEQ | specifies the name of the animation sequence |  |
STARTFRAME | specifies the frame at which the animation starts |  |
NUMFRAMES | specifies the number of frames in the animation |  |
RATE | frames per second (though the duration of the anim is set in PlayAnim() calls) |  |
Yes
GROUP | which group to place the anim in |  | Yes

Example:
#exec ANIM SEQUENCE ANIM=TozcAnim1 SEQ=All STARTFRAME=0 NUMFRAMES=25 RATE=0.2 GROUP=Default

#exec ANIM DIGEST
Once you've imported animations, a DIGEST command needs to be issued, at which point all sequences are compressed into the internal key track format.

Parameter | Description | Possible values | Optional?
ANIM | specifies the UAnimation object to "digest" the animations into |  |
VERBOSE | specify 'VERBOSE' to see more information in UCC.log after the rebuild |  | Yes

Example:
#exec ANIM DIGEST ANIM=SkAnimTest VERBOSE

#exec ANIM NOTIFY
Create a notifcation callback, must be placed after the ANIM DIGEST.

Parameter | Description | Possible values | Optional?
ANIM | specifies the animation to link the notification to |  |
SEQ | specifies the name of the animation sequence |  |
TIME | call the notify function after this fraction of the animation has played (e.g. 0.1 = 1/10th) | 0 - 1 |
FUNCTION | specifies the name of the function to call |  |

Example:
#exec ANIM NOTIFY ANIM=TozcAnim1 SEQ=All TIME=0.1 FUNCTION=LandThump

#exec MESH DEFAULTANIM
Link a UAnimation object to a skeletal mesh at compile time.

Parameter | Description | Possible values | Optional?
MESH | specifies the skeletal mesh to link the animations to |  |
ANIM | specifies the UAnimation object to link |  |

Example:
#exec MESH DEFAULTANIM MESH=MeshSk ANIM=SkAnimTest

#exec MESH BOUNDINGBOX
Override the engine's default bounding box with one that better fits the model.

Parameter | Description | Possible values | Optional?
MESH | specifies the mesh to define the bounding box for |  |
XMIN, YMIN, ZMIN | define the lower bounds of the box |  |
XMAX, YMAX, ZMAX | define the upper bounds of the box |  |

Example:
#exec MESH BOUNDINGBOX MESH=MeshSk XMIN=-64.0 YMIN=-64.0 ZMIN=-64.0 XMAX=64.0 YMAX=64.0 ZMAX=64.0

#exec MESH WEAPONATTACH
Define which bone is the weapon carrier.

Parameter | Description | Possible values | Optional?
MESH | specifies the mesh we're defining the weapon bone for |  |
BONE | the name of the bone to assign as weapon carrier |  |

Example:
#exec MESH WEAPONATTACH MESH=MeshSk BONE="Right hand"

#exec MESH WEAPONPOSITION
Define the location of the attachment point, relative to the weapon carrier bone.

Parameter | Description | Possible values | Optional?
MESH | specifies the mesh we're dealing with |  |
YAW, PITCH, ROLL | specifies the rotation of the weapon attachment point |  |
X, Y, Z | specifies the location of the weapon attachment point |  |

Example:
#exec MESH WEAPONPOSITION MESH=MeshSk YAW=50 PITCH=0 ROLL=10 X=0.0 Y=0.0 Z=0.0


Flamethrower

by c0mpi1e

//================================================
// FireBitch.
// Same as GasBagBelch only has a shorter life-time - serves as the flame
//================================================
class FireBitch expands GasBagBelch;

Here we go! The Firebitch is a subclassed GasBagBelch - it is the projectile you get when firing the FlameThrower. Ok, as you know the PostBeginPlay function/event (both the same in Unreal) is called directly before the object is spawned in the level.
function PostBeginPlay()
{
if ( ScriptedPawn(Instigator) != None )
Speed = ScriptedPawn(Instigator).ProjectileSpeed / 2;
PlaySound(SpawnSound);
Velocity = Vector(Rotation) * speed;
MakeNoise ( 1.0 );
Texture = SpriteAnim[0];
i=1;
SetTimer(0.15,True);
Super.PostBeginPlay();
}

This essentially slows down the GasBagBelch by half i.e. the slash 2. Ok, now we kick into the Flying state. This occurs when the projectile is spawned.
auto state Flying
{

HitWall believe it or not, is called when the object smacks into a solid object in Unreal, which isn't a pawn or similar.
simulated function HitWall( vector HitNormal, actor Wall )
{

// For a cool effect if the smoke hits the wall
// or the floor then start a smoke puff that keeps
// going for a while
if (Frand() > 0.6)
{
spawn(class'ShortSmokeGen',,,Location+HitNormal * 9);
Destroy();
}
}

Process Touch occurs when the object hits an actor. It passes the reference to the actor, and the vector (3d coords) of where the firebitch hit. Notice that if the player who created the FireBitch is the one who gets hit, then no damage occurs. Otherwise, the TakeDamage function of the other actor is called to take burn damage.
function ProcessTouch (Actor Other, Vector HitLocation)
{
if (Other != instigator)
{
// Change from just regular Damage
 Other.TakeDamage(Damage/2, instigator,HitLocation,
15000.0 * Normal(velocity), 'burned');

ExplodeCheck(HitLocation, Vect(0,0,0), 1);
}
}

ExplodeCheck checks whether or not the FireBitch should produce an explosion effect. If the shottype is 0, then call the explode function. Theres a fifty-fifty chance then of creating a flame explosion effect.
function ExplodeCheck(vector HitLocation, vector HitNormal, int shottype)
{
if (shottype == 0)
{
Explode(HitLocation, Vect(0, 0, 0));
return;
}
if (FRand() < 0.5)
MakeNoise(0.1);
spawn(class'FlameExplosion',,,HitLocation+HitNormal * 9);
Destroy();
}

Explode is called when the firebitch has been determined to explode. If it does explode, make a noise.
function Explode(vector HitLocation, vector HitNormal)
{
if (FRand() < 0.5)
MakeNoise(0.1); //FIXME - set appropriate loudness
Destroy();
}

The begin label is where the actual code starts after the Post event. It lives for 0.9 seconds before calling ExplodeCheck to determine whether it should stop. For example, if you wanted the FireBitch to last for 2 secs, then input Sleep( 2.0 ).
Begin:
// Changed from 3 to 0.3
 Sleep(0.9);
ExplodeCheck(Location, Vect(0,0,0), 0);

}

//===============================================
// FlameThrower.
// ==============
// created by c0mpi1e
// create a flame thrower using the gasbagbelch projectile
//
// Advantages:
// ++++very very deadly at close range
// Disadvantages:
// ++++only a close range weapon, and when shot reduces visiblity
//
//===============================================
class FlameThrower expands GESBioRifle;

The EXEC command loads in game experience data (audio, visual, mesh, etc). In this case, it loads in a flame sound created by c0mpi1e, and names it 'flame'. This sound can then be called by the PlaySound function.
#exec AUDIO IMPORT FILE="Sounds'TornSounds.flame.wav'" NAME="flame"
GROUP="FlameThrower"

var() int length;
var() Projectile Gel;
var() int i;

Again, this is called when the object spawns. It basically changes the class that it fires to FireBitch rather than GasBagBelch.
function PreBeginPlay()
{
length = 0;
i = 0;
Super.PreBeginPlay();

ProjectileClass = class'FireBitch';
ProjectileSpeed = class'FireBitch'.default.speed;
AltProjectileClass = class'FireBitch';
AltProjectileSpeed = class'FireBitch'.default.speed;
}

When the user hits primary fire, this code takes place. It calculates where the player is, adjusts the aim to take into account of the projectile, and then files a FireBitch.
function Projectile ProjectileFire(class ProjClass, float ProjSpeed, bool bWarn)
{
local Vector Start, X,Y,Z;
Owner.MakeNoise(Pawn(Owner).SoundDampening);
GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X
+ FireOffset.Y * Y + FireOffset.Z * Z;
AdjustedAim = pawn(owner).AdjustToss(ProjSpeed, Start, 0,
True, (bWarn || (FRand() < 0.4)));
return Spawn(ProjClass,,, Start,AdjustedAim);
}

Alternate fire.
function AltFire( float Value )
{

bPointing=True;
if ( AmmoType.AmmoAmount != 0 )
{

CheckVisibility();
GoToState('AltFiring');
}
else
GoToState('Idle');
}

Both Normal and Altfire modes are the same, so just make Fire point to the altfire code.
function Fire( float Value )
{
bPointing=True;
if ( AmmoType.AmmoAmount != 0 )
{
CheckVisibility();
GoToState('AltFiring');
}
else
GoToState('Idle');
}

We would like to overide the alt firing function because we are inheriting from the bio rifle, and it charges for its alt fire. We would like to keep shooting as long as the button is pressed down and the ammo is not used up there fore just call shoot load which will handle everything.

state AltFiring
{
  function Tick( float DeltaTime )
  {
  }

Begin:
  GotoState('ShootLoad');
  Finish();
}

state ShootLoad
{
  function Fire(float F) {}
  function AltFire(float F) {}
  function BeginState()
  {
    Super.BeginState();
  }
Begin:

  // Ok, shoot a projectile 10 times for every shot
  // makes the streaming more fluid because we force
  // the shot to shoot 10 times, so no matter what the
  // rendering speed 10 shots will be shot.
  // FIXME--fix that damn rendering problem, i have a
  // --suspicion that a timer would help but I'm sick of
  // --this thing already

  while (i < 10)
  {
    // Because we take command of shooting away from
    // function AltFire we have to control the ammo here

    if (AmmoType.AmmoAmount != 0)
    {
      // Call the shooting function

      Gel = ProjectileFire(AltProjectileClass, AltProjectileSpeed, bAltWarnTarget);

      // And set the drawscale to make the baggasbelch larger
      Gel.DrawScale = 4;

      // Then play the flame sound
      Owner.PlaySound(FireSound, SLOT_Misc,
1.7*Pawn(Owner).SoundDampening,,,fMax(0.5,1.35-ChargeSize/8.0) );  //shoot goop

      // For every fifth shot fired take off ammo
      // you could also say if i == 5 but this
      // way you can change the while condition
      if (i % 5 == 0)
        AmmoType.UseAmmo(1);

      // For effect if ammo is under 15 then weeze out the shots
      if (AmmoType.AmmoAmount < 15)
        if (FRand() > 0.8)
          {
            FinishAnim();
            break;
          }

      // Pause a sec so the shots don't all come out at once
      Sleep(0);
      i++;
    }
  }

  // Play gun firing anim.
  PlayAnim('Fire',0.4, 0.05);

  i = 0;
  Finish();
}


Floating Actor Tips

by Joachim Lous

Joachim Lous

This tutorial explains the basics of adding floating pop-up labels in the hud that track objects in the game, much like the info frames in DeusEx (if you enhance the rendering quite a bit). I call them ActorTips.

First of all we need to create a new HUD-type that implements the ActorTip feature. Here we'll add it to the normal UT ChallengeHUD, but you could base it on any HUD-type available to you:

class TipHUD expands ChallengeHUD;

Now, we need to decide which object(s) we're going to label. You can of course make that selection according to any criteria you wish (your friends, objects in a certain state, or ones you've previously somehow selected), but for this example we'll just make a guess at which object the player is most likely "looking" at:

simulated function Actor GetFocusedActor()
{
local vector Look, EyePos;
local Actor Candidate, Winner;
local float Score, HiScore;

// Find out where the camera is, and where it's looking:
EyePos = Owner.Location;
EyePos.Z += Pawn(Owner).EyeHeight;
Look = vector(Pawn(Owner).ViewRotation);

// Iterate through all actors closer than 200 UUs to the player,
// trying to find the one most directly in front of him:
HiScore = 0;
foreach VisibleActors(class'Actor', Candidate, 200.0, EyePos)
{
// The dot product of two normalised vectors is a nice
// measure of the angle between them:
// (1 = perfect match, 0 = right angles, -1 = direct opposites)
Score = Normal(Candidate.Location - EyePos) dot Look;

// Ignore actors too far to the sides (too low scores):
if (Score >= 0.9) // adjust this threshold to taste
{
// See if this candidate is an improvement:
if (Score > HiScore)
{
HiScore = Score;
Winner = Candidate;
}
}
}

return Winner;
}

We also need to work out where on the screen an object will appear, based on its 3D coordiantes, so we can position our floating graphic correctly on top of it. (The math is explained in the appendix at the end.)

simulated function vector MapToScreen(vector TargetPos, Canvas Canvas)
{
local vector Result, EyePos;
local rotator Look, Focus;
local float TanFOV, dYaw, dPitch, scale;

// Again, our current point of view is sort of essential:
EyePos = Owner.Location;
EyePos.Z += Pawn(Owner).EyeHeight;

// Find out where we're facing, but his time as a 'rotator' providing
// angles rather than a vector:
// (The conversion to vector and back is just a suboptimal but robust
// way to make sure we get nice signed values for the pitch, instead
// of wrap-around from 0 to 65535 at the horizon).
Look = rotator(vector(Pawn(owner).ViewRotation));

// Find the corresponding rotator angles of the direction from
// the camera to our target:
Focus = rotator(TargetPos - EyePos);

// Now find out how much the target angles are offset from the
// look angles. (And while we're at it, convert to radians, since
// that's what Unreal's trig functions work with):
dYaw = (focus.yaw-look.yaw) * Pi / 32768.0;
dPitch = (focus.pitch-look.pitch) * Pi / 32768.0;

// The field of view obviously affects how things are projected
// to the screen, as does the canvas resolution.
// In fact, the two can be combined into a single scaling factor
// that tells us all we need to know.
Scale = (Canvas.ClipX/2) / tan(Pawn(Owner).FOVangle * Pi / 360.0);

// Finally calculate actual screen coordinates:
Result.x = Canvas.ClipX/2 + tan(dYaw) * Scale;
Result.y = Canvas.ClipY/2 - tan(dPitch) * Scale;

return Result;
}

Now that we have the tools we need, we do the actual drawing. For this tutorial we just print the name of the object over it, but you could write any other information, or draw icons or frames or anything you like. This function also wraps up our entire HUD module in a single call:

simulated function DrawActorTip(Canvas Canvas)
{
local Actor FocusedActor;
local vector ScreenPos;

// Find Target
FocusedActor = GetFocusedActor();

// Label Target
if (FocusedActor != None)
{
Canvas.DrawColor = WhiteColor;
Canvas.Style = ERenderStyle.STY_Translucent;
Canvas.Font = MyFonts.GetSmallFont( Canvas.ClipX );
ScreenPos = MapToScreen(FocusedActor.Location, Canvas);
Canvas.SetPos(Screenpos.x, Screenpos.y);
Canvas.DrawText(FocusedActor.Name);
}
}

Finally we need to make sure our drawing routine is actually called each time the HUD is rendered:

// Override the old HUD-redrawing function:
simulated function PostRender(Canvas Canvas)
{
// -But make sure all the old drawing is still done first:
// (If you want to, that is)
super.PostRender(Canvas);

// Then add our ActorTip on top:
DrawActorTip(Canvas);
}

And it's done!

APPENDIX:

The math of projecting a direction-offset onto the screen.

The problem is to find out where the vector from the camera to the target will intersect the screen. We can solve this for X and Y separately. Considering X first, looking at the figure below, our problem is to figure out dx:

From the definition of the tangent we know that

dx
tan(dYaw) = ---
z

and that

ClipX/2
tan(FOV/2) = ----------
z

These easily reduce to:

ClipX/2
dx = tan(dYaw) -----------------
tan(FOV/2)

This is almost our code exactly. All we add is some conversion to radians and offsetting the origin to the centre of the canvas.

We then do the same thing for Y versus Pitch. Note that we then use same scaling fraction (with ClipX, not ClipY), since we don't have any separate vertical FOV.

Errata
Since publishing the tute the author has informed us the following:
"I've discovered a mistake in it: my way of projecting the position onto the screen is incorrect:
It works OK around horizontal, but when looking steeply up or down it becomes clear that the assumption that you can solve for X and Y separately doesn't hold"
We'll try to resolve this soon.


Grappling Hook

by mr. self-destruct

mrsd@beyondunreal.com

In this we shall go through how to make a grappling hook that uses real world physics. This grappling hook is a offshoot of Pfhoenix's early work on the RealGrapple, so thanks Pfhoenix, Frederico & Gopher42, this grapple wouldn't exist without you guys ;)

Theory

To allow the player to swing (and perform some cool stunts) with the grapple we need to approximate real world physics, in this particular case circular motion.
Angular velocity measures how rapidly something is rotating, angular velocity is the angle turned through in one second. The units for angular velocity is radians per second:

angular velocity = 2 x Pi / period of rotation
w = 2π / T

Any object moving in a circular path accelerates towards the centre of the circle. Newton's second law says that a force is needed to cause this acceleration. This is sometimes referred to as the centripetal force. The centripetal force is not an extra force that arises due to the circular motion; it is the resultant of all the real forces acting on the body:

centripetral force = mass x radius x angular velocity squared
F = mrw^2

So now we know the magnitude of the force required to make the player move in a circle. Note that this is a simplification of the problem, there are further complications, such as the effect of gravity when moving in a vertical circle. But we're only aiming for an approximation adequate enough to allow the player to swing on the grapple.

Code

Here comes the code for the grappling hook, I've implemented it as a weapon and even thrown in a chain effect that links the player to the grapple. The grapple works on an instant hit basis, as this allows the player to more readily pull of cool stunts. Lacking any custom models for the grapple gun or the chain, I've used some pre-existing UT meshes.

Grappling hook:

class GrapplingHook extends TournamentWeapon;

var bool bHooked;
var vector HookLocation, Force;
var float GrappleLength, Omega, CForce;
var int Counter;
var GChain Chain;

replication
{
// Things the server tells the client
unreliable if (ROLE == ROLE_Authority)
HookLocation, GrappleLength, bHooked;
}

simulated function Destroyed()
{
if (Chain != None)
Chain.Destroy();

Super.Destroyed();
}

simulated function Tick(float DeltaTime)
{
if (Owner == None) return;

if (bHooked)
{
if (Owner.Physics != PHYS_Falling)
{
StopGrapple();
return;
}
Counter++;
// Update angular velocity every 3rd tick; gives a less spiralled path
if (Counter == 3)
{
// Angular velocity
GrappleLength = VSize(HookLocation - Owner.Location);
// If the chain gets too long
if (GrappleLength > 2500)
{
StopGrapple();
return;
}
Omega = VSize(Owner.Velocity / GrappleLength) * DeltaTime;
Counter = 0;
}
// Centripetal force
CForce = Owner.Mass * GrappleLength * Omega ^ 2;
// Centripetal force is towards centre of circle
Force = Normal(HookLocation - Owner.Location);
Force *= CForce;
Owner.Velocity += DeltaTime * Force;
// Clamp maximum velocity
if (VSize(Owner.Velocity) > 1100)
Owner.Velocity = Normal(Owner.Velocity) * 1100;
else if (VSize(Owner.Velocity) < -1100)
Owner.Velocity = - (Normal(Owner.Velocity) * 1100);
}
}

function StartGrapple()
{
local vector X, Y, Z, End, HitLocation, HitNormal;
local Actor Other;

// Don't start grappling if we're already grappling
if (bHooked)
return;

GetAxes(Pawn(Owner).ViewRotation, X, Y, Z);

// End trace to stop people grappling stupidly long distances
Other = Trace(HitLocation, HitNormal, Owner.Location + X * 2500.0, Owner.Location);

if (Other == None)
return;

Other.TakeDamage(10.0, Pawn(Owner), HitLocation, 400.0 * X, 'grapple');

if (!Other.IsA('Pawn') && !Other.IsA('Projectile') && !Other.IsA('Decoration'))
{
bHooked = True;
HookLocation = HitLocation;
GrappleLength = VSize(HitLocation - Owner.Location);
if (Chain == None)
{
Chain = Spawn(class'StarterChain', Owner,, Owner.Location);
if (Chain.IsA('StarterChain'))
StarterChain(Chain).HookLocation = HookLocation;
}

// Give the player a "kick" to get them moving
Owner.Velocity += Normal(HookLocation - Owner.Location) * 200;
}
}

function StopGrapple()
{
bHooked = False;
if (Chain != None)
{
Chain.Destroy();
Chain = None;
}
}

// Fire to begin grappling
function Fire(float Value)
{
GotoState('NormalFire');
StartGrapple();
}

// AltFire to stop grappling
function AltFire(float Value)
{
GotoState('AltFiring');
StopGrapple();
}

state NormalFire
{
ignores Fire, AltFire;
Begin:
FinishAnim();
LoopAnim('boltloop');
Finish();
}

state AltFiring
{
ignores Fire, AltFire;
Begin:
FinishAnim();
LoopAnim('idle');
Finish();
}

// Putting down weapon in favor of a new one
state DownWeapon
{
ignores Fire, AltFire, AnimEnd;

function BeginState()
{
Super.BeginState();
bCanClientFire = false;
// Destroy chain
bHooked = False;
if (Chain != None)
{
Chain.Destroy();
Chain = None;
}
}
}

defaultproperties
{
Counter=0
PickupMessage="You got a Grapple Gun"
ItemName="Grappling Hook"
Mesh=LodMesh'Botpack.PulsePickup'
InventoryGroup=1
PlayerViewOffset=(X=1.500000,Z=-2.000000)
PlayerViewMesh=LodMesh'Botpack.PulseGunR'
PickupViewMesh=LodMesh'Botpack.PulsePickup'
ThirdPersonMesh=LodMesh'Botpack.PulseGun3rd'
ThirdPersonScale=0.400000
}

Chain (two classes), essentially a tweaked form of PBolt:

class GChain extends Projectile;

var GChain Chain;
var int Position;
var float BeamSize;

simulated function Destroyed()
{
Super.Destroyed();
if (Chain != None)
Chain.Destroy();
}

simulated function CheckBeam(vector X, float DeltaTime)
{
if (Position * BeamSize < 2500.0)
{
if ( Chain == None )
{
Chain = Spawn(class'GChain',,, Location + BeamSize * X);
Chain.Position = Position + 1;
}
else
Chain.UpdateBeam(self, X, DeltaTime);
}
}

simulated function UpdateBeam(GChain ParentChain, vector Dir, float DeltaTime)
{
SetLocation(ParentChain.Location + BeamSize * Dir);
SetRotation(ParentChain.Rotation);
CheckBeam(Dir, DeltaTime);
}

defaultproperties
{
BeamSize=81.000000
MaxSpeed=0.000000
bNetTemporary=False
Physics=PHYS_None
RemoteRole=ROLE_None
LifeSpan=60.000000
Skin=Texture'Botpack.Skins.pbolt0'
Mesh=LodMesh'Botpack.PBolt'
bUnlit=True
bCollideActors=False
bCollideWorld=False
}
class StarterChain extends GChain;

var vector HookLocation;

replication
{
// Things the server tells the client
unreliable if (ROLE == ROLE_Authority)
HookLocation;
}

simulated function Tick(float DeltaTime)
{
// Just to ensure that the chain disappears when the grappling hook is not in use
if (!PlayerPawn(Owner).Weapon.IsA('GrapplingHook'))
Destroy();
// orient with respect to instigator
if ( Instigator != None )
{
SetRotation(rotator(HookLocation - Location));
SetLocation(Instigator.Location);
}
CheckBeam(Normal(HookLocation - Location), DeltaTime);
}

defaultproperties
{
Skin=Texture'Botpack.Skins.sbolt0'
RemoteRole=ROLE_SimulatedProxy
}

And there you have it, a working grappling hook. It takes some practice to get the hang of using it properly (hint: take a running jump before grappling), but it's great fun once you've mastered it. The grappling hook works in network games too, but does lack bot support (anyone fancy having a go at adding bot support?).


Grenade Launcher

by crack_addict

Okay, heres a simple and unimaginative grenade launcher that subclasses TournamentWeapon instead of a pre-existing weapon. I've tried to be as thorough as I can in describing whats going on in the major parts of how a weapon works. All the grenade launcher does is launch a single grenade in primary mode, and 3 in alt fire mode, and a lot of the code here is unnecessary, but I included it to hopefully help explain whats going on.
// ==========================================
// Grenade Launcher
// ==========================================
class GrnLauncher expands TournamentWeapon;

Any of the Play____() functions are animation functions and you should override them in your new weapons to play the right animations for your new mesh. In this case I'm using the Unreal Eightball mesh, so all I have to do is have it play those animations.

The PlayAnim() function plays animations (duh), using the name of the animation, rate of play, and finally tweentime. An easy way to make a weapon fire faster is to simply increase the rate at which the firing animation plays, since UT's weapons depend on the animation length as its timing. Tweening is a method Unreal uses to smooth out changes in animation keyframes, so if the weapon is already playing an animation, it will blend into the new Fire animation.
function PlayFiring()
{
PlayAnim( 'Fire', 0.6, 0.05);
}

// The eightball mesh from Unreal doesn't have a specific AltFire
// animation, so I just have it play the normal Fire animation.
function PlayAltFiring()
{
PlayFiring();
}

When the player presses the fire key/button, the Fire() function in PlayerPawn is called, which in turn calls the Fire() function of the currently selected weapon. Then the weapon tries to use some ammo, and then begins the firing process, either calling the TraceFire() function if bInstantHit is set to true (the sniper rifle and minigun are examples of this), or its calls the ProjectileFire() function which we use here.
function Fire( float Value )
{
// AmmoType is a reference to our current Ammo, which is created
// when we pick up the weapon. The UseAmmo() function simply
// returns true and subtracts if it has amount of ammo specified.
 if (AmmoType.UseAmmo(1))
{
// Then the weapon goes to the NormalFire state, which is a good
// place to override functions that should be different from
// the AltFiring mode, ie in this case the ProjectileFire()
// function needs to be changed from each mode.
 GotoState('NormalFire');

// The ShakeView() shakes the view of the player (duh), and
// by tweaking these values you can add to the effect of a weapon.
 if ( PlayerPawn(Owner) != None )
PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
bPointing=True;

// Play the firing animation...
 PlayFiring();
if ( !bRapidFire && (FiringSpeed > 0) )
Pawn(Owner).PlayRecoil(FiringSpeed);

// If bInstantHit is set to true, then call TraceFire(), otherwise
// call the ProjectileFire() function.
 if ( bInstantHit )
TraceFire(0.0);
else
ProjectileFire(ProjectileClass, ProjectileSpeed, bWarnTarget);

if ( Owner.bHidden )
CheckVisibility();
}
}

States are a feature of Unrealscript that allow you to have different code executed within the same class, allowing you to easily add new functionality to your code without rewrite all of it. Weapons have 2 separate firing states, NormalFire and AltFiring. In our weapon we want the normal fire to shoot a single grenade, while altfire will shoot 3 of them, so really we only have to override the ProjectileFire() class in the AltFiring state, but I've overridden it in NormalFire too to explain how it works.
state NormalFire
{
// ProjectileFire() is responsible for creating a new projectile in
// the proper location, facing the right direction.
 function Projectile ProjectileFire(class<projectile> ProjClass,
float ProjSpeed, bool bWarn)
{
local Vector Start, X,Y,Z;
local Pawn PawnOwner;

PawnOwner = Pawn(Owner);
Owner.MakeNoise(PawnOwner.SoundDampening);

// GetAxes() will get the 3d axes based upon the given rotation,
// so in this case it gets X (the forward-back), Y (the left-right),
// and Z (the up-down) axes to use in calculating the start spot.
 GetAxes(PawnOwner.ViewRotation,X,Y,Z);

// Start is calculated by taking the weapon owner's location, adding
// the value generated by the CalcDrawOffset() function and then
// adding the various values stored in FireOffset to the appropriate
// axes. FireOffset.X * X basically means move the point over
// however much is stored in FireOffset.X in the direction X is pointing.
// CalcDrawOffset(), which is defined in Inventory, calculates the
// EyeHeight of the owner, plus the bob of the weapon.
 Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X +
FireOffset.Y * Y + FireOffset.Z * Z;

// AdjustedAim is the direction the projectile will be facing and is
// generated by a function in Pawn called AdjustAim(). AdjustAim()
// basically takes the direction the weapon's owner is facing and
// then adds in auto-aim, aimerror, etc. You could also try:
// AdjustedAim = 100000 * X;
// and it would work just the same, since that would be pointing to
// a far away point along the X axis, which is straight ahead, but
// it is a good idea to stick with AdjustAim().
 AdjustedAim = PawnOwner.AdjustAim(ProjSpeed, Start, AimError, True, bWarn);

// And finally create the projectile and return it.
 return Spawn(ProjClass,,, Start,AdjustedAim);
}

// These are here so that you can't fire while the weapon is already
// firing. Otherwise the timing of the firing would be off, since
// it would no longer have to wait for the animation to finish.
 function Fire(float F)
{
}
function AltFire(float F)
{
}

Begin:
// FinishAnim() is a latent function that pauses execution of the code
// until the current animation being played finishes. The Unreal/UT
// weapon code depends on this wait for timing, so if you remove this
// call for some reason it will throw off the timing of your weapon.
// Try removing it from the minigun sometime for an interesting
// effect. :)
 FinishAnim();

// Finish(), defined in Weapon simply checks to see if the weapon is
// out of ammo and switches to a new weapon if it is, and checks to see
// if the player still has the button down, and if so fires again, otherwise
// it goes to the Idle state to play some idling animations and wait
// to fire again.
 Finish();
}

state AltFiring
{
// This is the same version as in the NormalFire except that I've
// altered it slightly to produce 2 more grenades, instead of just
// the one.
 function Projectile ProjectileFire(class<projectile> ProjClass,
float ProjSpeed, bool bWarn)
{
local Vector Start, X,Y,Z;
local Pawn PawnOwner;
local rotator newAdjustedAim;

PawnOwner = Pawn(Owner);
Owner.MakeNoise(PawnOwner.SoundDampening);
GetAxes(PawnOwner.ViewRotation,X,Y,Z);
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X +
FireOffset.Y * Y + FireOffset.Z * Z;
AdjustedAim = PawnOwner.AdjustAim(ProjSpeed, Start, AimError, True, bWarn);

// For the hell of it, lets spawn the grenades at a slight angle
// to either side of the original.
 newAdjustedAim = AdjustedAim;
newAdjustedAim.Yaw += 4096; // 65535/16 ~= 23 degrees

// Then go ahead and create a grenade pointing at the new direction.
Spawn(ProjClass,,, Start, newAdjustedAim);

// Lets do the next one, on the other side and create it.
 newAdjustedAim.Yaw -= 8192; // 4096*2 = 46 degrees...the other direction
Spawn(ProjClass,,, Start, newAdjustedAim);

// And finally the original one...
 return Spawn(ProjClass,,, Start,AdjustedAim);
}

function Fire(float F)
{
}
function AltFire(float F)
{
}

Begin:
FinishAnim();
Finish();
}

With a new weapon you must specify an Ammo, otherwise the weapon won't work (Fire() depends on it). In this case I just used the rocket ammo from UT, since I didn't have a new mesh or anything. If you're using UnrealEd the defaultproperties will be hidden to you, but you can edit them by right-clicking on the class and selecting Edit Default Properties. If you use a text editor + ucc you can just add the AmmoName=Class'Botpack.RocketPack' line like I did down below. Any variable can have its default value set here, and some important ones to remember for weapons are AmmoName, ProjectileClass if its a projectile weapon, or bInstantHit for hitscan weapons. Check out the Weapon class for more info on the rest of the ones listed here.

defaultproperties
{
     AmmoName=Class'Botpack.RocketPack'
     PickupAmmoCount=6
     ProjectileClass=Class'UnrealShare.Grenade'
     AltProjectileClass=Class'UnrealShare.Grenade'
     shakemag=350.000000
     shaketime=0.200000
     shakevert=7.500000
     AIRating=0.700000
     RefireRate=0.250000
     AltRefireRate=0.250000
     AltFireSound=Sound'UnrealShare.Eightball.EightAltFire'
     SelectSound=Sound'UnrealShare.Eightball.Selecting'
     DeathMessage="%o was smacked down multiple times by %k's %w."
     AutoSwitchPriority=5
     InventoryGroup=5
     PickupMessage="You got the grenade launcher"
     ItemName="GrenadeLauncher"
     PlayerViewOffset=(X=1.900000,Z=-1.890000)
     PlayerViewMesh=LodMesh'UnrealShare.EightB'
     BobDamping=0.985000
     PickupViewMesh=LodMesh'UnrealShare.EightPick'
     ThirdPersonMesh=LodMesh'UnrealShare.8Ball3rd'
     StatusIcon=Texture'Botpack.Icons.Use8ball'
     PickupSound=Sound'UnrealShare.Pickups.WeaponPickup'
     Mesh=LodMesh'UnrealShare.EightPick'
     bNoSmooth=False
     CollisionHeight=10.000000
     bInstantHit=false
     bAltInstantHit=false
}


HUD Overview and Canvas functions

by Eater

NaliChronicles

Who this tutorial is for

This tutorial is a detailed overview of all the wonderful things you can do with HUDs and the Canvas class. Although I do mention some things on how to create a simple HUD, this tutorial is geared more towards advanced coders that want to find out a few more tricks about making good HUDs. If you've never made a HUD before you may find yourself a little confused. This is normal. Feel free to mail me any questions you may have at lsergey@home.com.

Canvas and where it all begins

First off, whenever you're making a HUD, you should remember that everyone a HUD draws is drawn on the Canvas. The Canvas is basically an object that draws thing directly on the player's screen. If you've ever coded Java applets, the Graphics object is probably the closest thing to the UT Canvas I can think of. The HUD is basically a set of instructions that tell the Canvas object what to draw and where. The HUD is redrawn as often as possible (every tick I believe). Whenever the HUD is redrawn, the "PostRender(Canvas Canvas)" function is called. This function is called by the PlayerPawn and gives you access to the Canvas class so you can draw things on it. The PlayerPawn also calls the PostRender function of weapons for things like custom crosshairs (like for the rocket launcher), but we'll focus on just the HUD for now. Another thing to keep in mind about the HUD is that in multiplayer games it exists client-side (since there is no need for the server to know what the player has going on with his HUD), so you should put "simulated" before all the functions to ensure your own well being.

"What this all means to me"

If you don't feel like figuring out what I said above, here is a summary of what all that means to you, a guy that just wants to make a custom HUD: The whole HUD process starts with the "PostRender(Canvas Canvas)" function which is called about every tick (in other words, as often as possible). All the drawing is done by the Canvas object. You should put "simulated" before all your functions in your HUD. Simple enough, right? Good.

Making and using the HUD

Before I go into detail about how to actually draw pictures and text on the HUD, I want to explain where and how you can use this HUD. The best place to use new HUD objects is in a new gametype. I'm not sure about mutators however, as it may be possible to modify the HUD with a mutator without having to create a new HUD object. If, however, you want to use your HUD in a new gametype just set the HUDType property of your new gametype to the class name of your HUD. For most UT modifications, you'll want to subclass ChallengeHUD, although if you're making a more total conversion you might want to subclass the HUD class.

Basic functions and variables

As stated before, all the drawing is done by the Canvas object, sent to the HUD through the PostRender(Canvas Canvas) function. Note that if you want to draw things on the HUD with other functions besides PostRender, be sure to send the Canvas object to them too so they actually have something to draw on. Now without any further comments, here is my list of all the important functions and variables in the Canvas class:

font Font - this is the font that the Canvas will use when it draws text. I will explain more about fonts later on.

float OrgX, OrgY - these are the coordinates of the point (0,0). Usually you won't alter these, but there are situations (explained later on) where altering these values can be helpful.

float ClipX, ClipY - this is the bottom right corner of the drawing region. Depending on the resolution, these values will vary. Again, usually you won't alter these, but there are situations where it may be helpful.

float CurX, CurY - the current location for drawing. If you draw something, this is where it will be drawn.

byte Style - the style in which pictures or text will be drawn (transparent, masked, etc.). So if you want to draw a masked icon, make sure that the Style variable is set to STY_Masked.

color DrawColor - the color in which something will be drawn. The default is gray (127,127,127). If you draw a picture while the DrawColor is not white, that picture's colors WILL be altered. To alter the color, simply enter
Canvas.DrawColor.r = REDVALUE;
Canvas.DrawColor.g = GREENVALUE;
Canvas.DrawColor.b = BLUEVALUE;
where REDVALUE, GREENVALUE, and BLUEVALUE are the amounts of red green and blue you want in that color (255 is the max amount you can set per color).

function StrLen( coerce string String, out float XL, out float YL ) - return the dimensions of the string String (XL and YL) based on the currently selected font.

function DrawText( coerce string Text, optional bool CR) - draws the string Text at (CurX,CurY) with the font Font.

function DrawTile( texture Tex, float XL, float YL, float U, float V, float UL, float VL) - used for drawing parts of an icon or drawing an icon with irregular dimensions. This function will be discussed later on.

function DrawActor( Actor A, bool WireFrame, optional bool ClearZ ) - draws the actor A on the player's screen. This only makes sense if the actor A is normally hidden. The only place I've seen this used is by the weapon class for drawing the first person model.

function DrawPortal( int X, int Y, int Width, int Height, actor CamActor, vector CamLocation, rotator CamRotation, optional int FOV, optional bool ClearZ ) - draws a rectangular area that displays the view from another actor. Most of the values are pretty obvious. In my own experience I've noticed that this function doesn't always work. If you are having trouble, make sure FOV is set to 90.

event Reset() - resests all the variables to their defaults. Useful for cleaning up after you do something messy (more below).

function SetPos( float X, float Y ) - sets CurX to X and CurY to Y, just like writing CurX = X; CurY = Y; only faster.

function SetOrigin( float X, float Y ) - sets OrgX to X and OrgY to Y, just like writing OrgX = X; OrgY = Y; only faster.

function SetClip( float X, float Y ) - sets ClipX to X and ClipY to Y, just like writing ClipX = X; ClipY = Y; only faster.

function DrawPattern ( texture Tex, float XL, float YL, float Scale ) - draws a repeating pattern with sizes XL and YL and with a scale Scale (that scale is applied to each "picture" in the pattern). Note that the pattern is drawn as if it started at (0,0), so if you're drawing in around the middle of the screen don't be surprised if you don't have the upper-left hand corner of Tex in the upper-left hand corner of your pattern (if you want to know what I mean, test this function out for yourself). Also, keep in mind that the scale is reversed, so if you enter 0.5 the images will be 2x BIGGER, and with scale 2 they will be 2x SMALLER.

function DrawIcon ( texture Tex, float Scale ) - draws the icon Tex with a scale factor Scale. You will probably be using this a lot.

function DrawRectangle ( texture Tex, float RectX, float RectY ) - draws the icon Tex with a horizontal scale of RectX and a vertical scale for RectY.

Drawing from the bottom-right

This is really a beginner thing, but just so you know, if you want to draw an icon along the bottom of the screen, since the coordinates of the bottom will change with the resolution (as well as the coordinates for the right edge), you should use ClipX and ClipY (that is after all what they're there for). So if you want to draw a 64x64 pixel icon in the lower right-hand corner, you would set the CurX to ClipX-64 and CurY to ClipY-64.

Fonts

The Font variable in the Canvas class represents the font with which a text string will be drawn. You can set this to any Font you want, but there are some predefined Fonts in ChallengeHUD you should be aware of. Since the UT HUD, unlike the Unreal HUD, changes depending on a player's resolution (so if you increase the resolution the icons will be made bigger so as to compensate), the fonts have to change with the resolution too. So if you are making a HUD that changes with the resolution, you may want to use the predefined font functions. The FontInfo class is a UT class that determines what font you should use depending on the player's current resolution. In the ChallengeHUD class, there is a FontInfo variable named "MyFonts". This class contains a lot of functions that return the font you want. Below is a list of all these functions. Note that you should enter the current horizontal resolution, ClipX, for Width:

function font GetHugeFont(float Width) - returns a HUGE font.
function font GetBigFont(float Width) - returns a big font.
function font GetMediumFont(float Width) - returns a medium font.
function font GetSmallFont(float Width) - returns a small font.
function font GetSmallestFont(float Width) - returns an even smaller font.
function font GetAReallySmallFont(float Width) - returns a really small font.
function font GetACompletelyUnreadableFont(float Width) - returns a completely unreadable font.
Note that some of the smaller fonts may not have a full character set and you might only be able to use numbers.

Text wrapping and the use of origins and clips

By default, if you draw some text at the edge of the screen it will be automatically wrapped to the opposite edge. Of course, this doesn't look very good and sometimes you need to draw a sort of "text box" with wrapped text (like the Unreal translator). I have some good news - you CAN do this.

The text wrapping is based on ClipX and OrgX. The Canvas class assumes these are the edges of the screen, but as I mentioned earlier, these variables can be changed. However, be sure never to lose the original value of ClipX and ClipY, unless you want to be drawing the rest of your HUD in a rather small portion of the screen. To start off, you'll want to have two local variables in your function for storing the original values of ClipX and ClipY. For this part of the tutorial, we'll call these variables TempX and TempY. Before you do anything, make sure TempX = ClipX and TempY = ClipY. Now that the original clip values are safe and sound, we can start messing around with them.

First you'll want to use the setOrigin function to set the upper left-hand corner of our text box, then you'll want to use the setClip function to determine the lower right-hand corner. Now you'll want to enter setPos(0,0) so that the text starts in the upper left-hand corner of the box, and your text box is all set. Now you can set the font, make sure the colors are set right, etc. etc. and draw your text (with a single DrawText function). After you're done with that, we have to clean things up so that we can draw other stuff on the Canvas after this. First of all you'll want to call Canvas.Reset() to clean things up, and then you'll want to set ClipX and ClipY back to TempX and TempY. That's it, you're done!

The Scale factor

NOTE: This section only applies to people subclassing the ChallengeHUD class.

As I mentioned before in the Fonts section, the UT HUD changes in size depending on the resolution to give the impression that it stays the same. It uses the floating point Scale, set in the SetupHUD() function, to control the size of just about everything, so you'll want to multiply the scale of your icons and the locations you enter by Scale. You may also want to multiply it by StatusScale, which is the scale of the HUD set in the menu (so it would be YourScaleOrLocation*Scale*StatusScale).

The almighty tile

The DrawTile function is a native function in the Canvas class that actually draws an image. All those DrawIcon and DrawPattern are just UnrealScript functions that use the DrawTile function. However, the DrawTile function can be used to do a lot of fun things. Here is a description of all the arguments of that function:

native(466) final function DrawTile( texture Tex, // this is the actual image you want to draw, simple enough
float XL, // the horizontal length of the thing we're drawing, in pixels
float YL, // the vertical length of the thing we're drawing, in pixels
float U, // The horizontal offset of the image (so if we're drawing an image 128 in length with XL 128 and UL 128 and we enter 64 here, it will look like 2 halves of the image on opposite sides. Still confused? Here is my ASCII art to the rescue:

//
//XL = 128, UL = 128, U = 0 ("before"):
//[op]
//
//XL = 128, UL = 128, U = 64 ("after"):
//p][o
//

float V, // The vertical offset of the image (so if we're drawing an image 128 in height with YL 128 and VL 128 and we enter 64 here, it will look like 2 halves of the image on opposite sides. Still confused? Imagine the above ASCII art but rotated 90 degrees...
float UL, // how much of the image Tex to draw (so if the image is 128 in length and we enter 64, we will draw half)
float VL // how much of the image Tex to draw (so if the image is 128 in height and we enter 64, we will draw half)
);

So, if our image is 128 in length and we have UL set to 64 and XL set to 64, we will draw half of the image.

If, under the same setup, we have XL set to 128, we will draw half of that image with 2x the horizontal scale (so half the image will cover the same area as the whole image with UL 128).

Also, there are a few things to keep in mind about U and V. First of all, remember that it has nothing to do with XL and YL, so if you have an image 128 in length and enter UL = 128 and XL = 64, entering U = 32 will NOT result in the image being cut in half as described in the above ASCII art (it will be cut into 1/4 and 3/4). Think of XL and YL as a scale applied after all the other stuff is done. Another thing to keep in mind is that the image will be moved to the left for U and up for V, not right and down as would seem to make sense.


Improved Chat Messages

by crack_addict

This little tutorial goes over how to override the Say (and TeamSay) functions found in the PlayerPawn code to let players use escape codes in their messages to relay information. To make everything nice and neat I just went ahead and created a new function ParseChatString that will take a message, parse it, modify it as necessary, and then return the modified message. Then I made new versions of Say and TeamSay that call my new function to modify their message and then send/display the modified message. So in theory all you would have to do to integrate this code into your modification would be to put these 3 functions inside of your new PlayerPawn subclass.

ParseChatString takes a message, then steps through it one character at a time looking for the escape character #. Once it finds the escape character it grabs the next character then inserts whatever data into a new modified message, and then continues on parsing looking for more escape sequences until the end of the string is reached, and finally it returns the modified message.
// function string ParseChatString(string Msg)
//
// escape codes:
// =============
// #N - player name
// #L - player location
// #S - player status (health/armor)
// #H - player health
// #A - player armor
// #B - buddies, lists friendly players within radius
// #W - player weapon
// #T - test code
// ## - print the '#' character
//
// The buddy code uses RadiusActors to find pawns, and then checks to make
// sure they are on the same team, if so adds them to the buddy list (bStr),
// then when its done goes back and rewrites bStr to be grammatically correct,
// i.e. it adds an "and" etc etc. I know, its a waste of time, but I got
// a kick out of the fact that it worked the first time. :)
//
// To add more codes just add more cases in the switch statement, and append
// the information onto nMsg.
//
// TODO:
// - maybe add multiple levels of escape codes, like #b:5 would return 5 buddies?
function string ParseChatString(string Msg)
{
local int i, amt, numBuddy, lBuddyLen;
local float BuddyRadius;
local string nMsg, tStr, bStr, lbStr;
local Inventory Inv;
local Pawn Buddy;
local PlayerReplicationInfo mPRI, bPRI;

BuddyRadius = 1500.0;
mPRI = PlayerReplicationInfo;

// step through the string and look for escape char
// Len(string) returns the length of the string
for (i = 0;i <= Len(Msg);i++)
{
// use mid to get the char at i in Msg since Msg[i] doesn't work
// Mid(string, pos, count) returns a string starting at pos and
// ending at pos+count, so to get one char we use a count of 1
if (Mid(Msg, i, 1) == "#")
{
// found escape char, now get the next char and parse
i += 1;
tStr = Mid(Msg,i,1);
// this is our main switch statement, to add more escape codes
// just add more cases in here
switch (tStr)
{
// player weapon - inserts weapon name
case "W":
nMsg = nMsg $ Weapon.ItemName;
break;
// player name - inserts this player's name
case "N":
nMsg = nMsg $ mPRI.PlayerName;
break;
// player location - inserts the player's location
case "L":
if (mPRI.PlayerLocation != NONE)
nMsg = nMsg $ mPRI.PlayerLocation.LocationName;
else if (mPRI.PlayerZone != NONE)
nMsg = nMsg $ mPRI.PlayerZone.ZoneName;
else nMsg = nMsg $ "somewhere";
break;
// player armor - inserts player's armor count
case "A":
amt = 0;
for (Inv = Inventory; Inv != NONE; Inv = Inv.Inventory)
if (Inv.bIsAnArmor)
amt += Inv.Charge;
nMsg = nMsg $ amt;
break;
// player health - inserts player's health
case "H":
nMsg = nMsg $ Health;
break;
// player status - inserts health & armor
case "S":
amt = 0;
for (Inv = Inventory; Inv != NONE; Inv = Inv.Inventory)
if (Inv.bIsAnArmor)
amt += Inv.Charge;
nMsg = nMsg $ "Health: " $ Health $ " Armor: " $ amt;
break;
// player buddies - inserts a list of friendly units within
// a defined radius
case "B":
numBuddy = 0;
foreach RadiusActors(class'Pawn', Buddy, BuddyRadius)
{
bPRI = Buddy.PlayerReplicationInfo;
if (Buddy != Self && Buddy.bIsPlayer && bPRI.Team == mPRI.Team)
{
lbStr = bPRI.PlayerName;
lBuddyLen = Len(lbStr);
if (numBuddy < 1)
bStr = lbStr;
else bStr = bStr $ ", " $ lbStr;
numBuddy++;
}
}

// backtrack a bit and add an "and" to the message if
// we had 2 or more buddies, to be grammatically correct
if (numBuddy >= 3)
bStr = Left(bStr, Len(bStr) - lBuddyLen) $ " and " $ lbStr;
else if (numBuddy == 2)
bStr = Left(bStr, Len(bStr) - lBuddyLen - 2) $ " and " $ lbStr;
else if (numBuddy == 0)
bStr = "nobody";

nMsg = nMsg $ bStr;
break;
// test - just a test to play around with
case "T":
nMsg = nMsg $ "<test>";
break;
// print the '#' character
case "#":
nMsg = nMsg $ "#";
break;
default:
break;
}
}
// if we didn't find an escape code just copy char straight over
// to the new message
else nMsg = nMsg $ Mid(Msg, i, 1);
}
// and finally return the new message
return nMsg;
}

Now all that's left is to change the Say and TeamSay functions to call the new ParseChatString function, and then call the original Say and TeamSay functions with the new message to be sent/displayed.
exec function Say( string Msg )
{
// parse the chat string
Msg = ParseChatString(Msg);

// and send up our new and improved message
Super.Say(Msg);
}

exec function TeamSay(string Msg)
{
// parse the chat string
Msg = ParseChatString(Msg);

// and send up our new and improved message
Super.TeamSay(Msg);
}

And that's that. If you want to use this you must put it in a new PlayerPawn subclass and then change your ut.ini or make a new gametype to make sure you spawn as that new class...but thats beyond the scope of this tutorial.


Key Mover

by crack_addict

What we're going to do is make a subclass of a normal mover and add some code that will check to see if the player has a "key" of a specified type. If they do then the mover will do its thing normally, otherwise it won't...that way you could add lifts/doors/etc in your levels that need a specific key. (editor's note: please use this code responsibly, the world doesn't need more "find-the-key" puzzles :)
// =============================================
// kmover.KeyMover
// =============================================
class KeyMover expands Mover;

// This will be the class of the item we will open for, be it
// a weapon, or a keycard or whatever. Just set this to the
// class in the properties of the mover in the level...
var() class keyclass;

state() BumpOpenTimed
{
// Bump is called when an actor "bumps" us, and the mover code
// uses this to check and see if it should do its thing, if its
// a bump-based mover. We'll just insert some code here to
// check to see if the bumper is a Pawn (player/bot), and then
// if they have our desired key. If so then we call the normal
// Bump() function in the Parent class, otherwise go ahead and
// abort now.
 function Bump(actor Other)
{
local Inventory key;

// BroadcastMessage("Bumped by "$Other.Name);

// First check to make sure this is a Pawn, cause they are
// only things that have inventories (i think:), and then
// make sure we have a keyclass to check for.
 if (Other.IsA('Pawn') && keyclass != NONE)
{
// BroadcastMessage("Other.Class: "$Other.Class$", keyclass: "$keyclass);

// Now we just use FindInventoryType() to see if they have
// a copy of our desired key in their inventory...
 key = Pawn(Other).FindInventoryType(keyclass);

// ...if so call the old Bump() function and let the mover
// do its thing.
 if (key != NONE)
{
// Broadcastmessage("Found key");
 Super.Bump(Other);
}
// ...otherwise just do nothing.
// else BroadcastMessage("Couldn't find key");
 }
}
}

Thats all there is to it. You could take this even farther by having special id numbers in your key class so that you had to have the right key with the right id, or maybe take it even farther and let the player try to hack the id number with a special key or something... :)


King of the Hill

by crack_addict

King of the Hill (KOTH for short) changes the goal of the game to being in a certain area for the longest amount of time, instead of the normal goal of getting the most frags. The way we accomplish this in UT is the creation of a new game type to make some basic gameplay changes and changes to the players (kothGame), a new ZoneInfo subclass (kothZone) to place in the level to designate the "Hill". We also have a new PlayerReplicationInfo subclass (kothPRI) to hold the time spent on the "Hill", a new HUD subclass to change the fragcount to display KOTH time instead, and a new scoreboard as well to do the same.

New game types are created under the GameInfo class, and they handle the basic rules-keeping of the game, creating/logging in players, creating/removing bots, and other miscellaneous stuff (like mutators and default inventory). Some noteworthy functions are InitGame() which initializes game data, Login() which handles when a new player (warm body) gets created in the game, RestartPlayer() which handles when a player (bot/human) is respawned, ScoreKill() which handles a death in the game, and finally SpawnBot() which handles the creation of new bots. If you are interested in making new game types, it is a good idea to run through GameInfo and DeathmatchPlus to get an idea of the setup.
// ============================================================
// koth.kothGame
// ============================================================

class kothGame expands DeathMatchPlus;

// Change InitGame to zero out the fraglimit since
// the point of the game isn't frags with koth.
event InitGame( string Options, out string Error )
{
Super.InitGame(Options, Error);

Fraglimit = 0;
}

// In order to keep track of the time the player has spent
// in the kothZone, we need to use a new PlayerReplicationInfo.
// In order to make sure our players use the new replication
// info we change the Default replication info class before
// they login, so that it is created instead of the normal
// one.
event playerpawn Login
(
string Portal,
string Options,
out string Error,
class<playerpawn> SpawnClass
)
{
// A quick change of the default class...
 SpawnClass.Default.PlayerReplicationInfoClass = class'koth.kothPlayerReplicationInfo';

// and then login as normal.
 return Super.Login(Portal, Options, Error, SpawnClass);
}

// RestartPlayer() is called whenever a player respawns, and
// we just use it to reset the ZoneEnterTime so as to not throw
// off the calculations.
function bool RestartPlayer( pawn aPlayer )

{
if (aPlayer.PlayerReplicationInfo.IsA('kothPlayerReplicationInfo'))
kothPlayerReplicationInfo(aPlayer.PlayerReplicationInfo).ZoneEnterTime = 0;
else if (aPlayer.PlayerReplicationInfo.IsA('kothBotReplicationInfo'))
kothBotReplicationInfo(aPlayer.PlayerReplicationInfo).ZoneEnterTime = 0;

return Super.RestartPlayer(aPlayer);
}

// ScoreKill() normally would determine who would get a frag
// for a kill, or a negative frag if it was a suicide. Instead
// we use it to check if the player that died was in a kothZone,
// and if so we calculate the time spent in the zone, just as
// in the ActorLeaving() function in kothZone. We need to do this
// because ActorLeaving() isn't called until the player respawns,
// so this way they can't just sit waiting to respawn and rack
// up time.
function ScoreKill(pawn Killer, pawn Other)
{
local kothPlayerReplicationInfo kPRI;
local kothBotReplicationInfo kBRI;

if (Other.IsA('PlayerPawn'))
{
if (PlayerPawn(Other).PlayerReplicationInfo.IsA('kothPlayerReplicationInfo'))
{
kPRI = kothPlayerReplicationInfo(PlayerPawn(Other).PlayerReplicationInfo);
if (kPRI.ZoneEnterTime != 0)
kPRI.ZoneExitTime = Level.TimeSeconds;
kPRI.TotalTime += kPRI.ZoneExitTime - kPRI.ZoneEnterTime;
kPRI.ZoneExitTime = 0;
kPRI.ZoneEnterTime = 0;
kPRI.bIsInZone = false;
BroadcastMessage(kPRI.PlayerName$" left with "$kPRI.TotalTime$" total time.");
}
}
else if (Other.IsA('Bot'))
{
if (Bot(Other).PlayerReplicationInfo.IsA('kothBotReplicationInfo'))
{
kBRI = kothBotReplicationInfo(Bot(Other).PlayerReplicationInfo);
if (kBRI.ZoneEnterTime != 0)
kBRI.ZoneExitTime = Level.TimeSeconds;
kBRI.TotalTime += kBRI.ZoneExitTime - kBRI.ZoneEnterTime;
kBRI.ZoneExitTime = 0;
kBRI.ZoneEnterTime = 0;
kBRI.bIsInZone = false;
BroadcastMessage(kBRI.PlayerName$" left with "$kBRI.TotalTime$" total time.");
}
}

BaseMutator.ScoreKill(Killer, Other);
}

// Bot's aren't as easy to change the default PlayerReplicationInfo,
// we have to alter the SpawnBot() function to change the class, and
// unfortunately we can't just call the Parent function after we
// make our change, so this is just another cut & paste.
function Bot SpawnBot(out NavigationPoint StartSpot)
{
local bot NewBot;
local int BotN;
local Pawn P;
local class<bot> BotSpawnClass;

if ( bRatedGame )
return SpawnRatedBot(StartSpot);

Difficulty = BotConfig.Difficulty;

if ( Difficulty >= 4 )
{
bNoviceMode = false;
Difficulty = Difficulty - 4;
}
else
{
if ( Difficulty > 3 )
{
Difficulty = 3;
bThreePlus = true;
}
bNoviceMode = true;
}
BotN = BotConfig.ChooseBotInfo();

// Find a start spot.
 StartSpot = FindPlayerStart(None, 255);
if( StartSpot == None )
{
log("Could not find starting spot for Bot");
return None;
}

// Get the spawn class and then change the replication
// info class, then try to spawn it normally.
 BotSpawnClass = BotConfig.CHGetBotClass(BotN);
BotSpawnClass.Default.PlayerReplicationInfoClass = class'koth.kothBotReplicationInfo';
NewBot = Spawn(BotSpawnClass,,,StartSpot.Location,StartSpot.Rotation);

if ( NewBot == None )
log("Couldn't spawn player at "$StartSpot);

if ( (bHumansOnly || Level.bHumansOnly) && !NewBot.bIsHuman )
{
log("can't add non-human bot to this game");
NewBot.Destroy();
NewBot = None;
}

if ( NewBot == None )
{
BotSpawnClass = BotConfig.CHGetBotClass(0);
BotSpawnClass.Default.PlayerReplicationInfoClass = class'koth.kothBotReplicationInfo';
NewBot = Spawn(BotSpawnClass,,,StartSpot.Location,StartSpot.Rotation);
}

if ( NewBot != None )
{
// Set the player's ID.
 NewBot.PlayerReplicationInfo.PlayerID = CurrentID++;

NewBot.PlayerReplicationInfo.Team = BotConfig.GetBotTeam(BotN);
BotConfig.CHIndividualize(NewBot, BotN, NumBots);
NewBot.ViewRotation = StartSpot.Rotation;
// broadcast a welcome message.
 BroadcastMessage( NewBot.PlayerReplicationInfo.PlayerName$EnteredMessage,
false );

ModifyBehaviour(NewBot);
AddDefaultInventory( NewBot );
NumBots++;
if ( bRequireReady && (CountDown > 0) )
NewBot.GotoState('Dying', 'WaitingForStart');
NewBot.AirControl = AirControl;

if ( (Level.NetMode != NM_Standalone) && (bNetReady || bRequireReady) )
{
// replicate skins
 for ( P=Level.PawnList; P!=None; P=P.NextPawn )
if ( P.bIsPlayer && (P.PlayerReplicationInfo != None) &&
P.PlayerReplicationInfo.bWaitingPlayer && P.IsA('PlayerPawn') )
{
if ( NewBot.bIsMultiSkinned )
PlayerPawn(P).ClientReplicateSkins(NewBot.MultiSkins[0],
NewBot.MultiSkins[1], NewBot.MultiSkins[2], NewBot.MultiSkins[3]);
else
PlayerPawn(P).ClientReplicateSkins(NewBot.Skin);
}
}
}

return NewBot;
}

defaultproperties {
HUDType=class'koth.kothChallengeHUD'
ScoreBoardType=class'koth.kothScoreBoard'
}

Zones are actors used to describe various areas in a level, such as water, lava, and in our case the "Hill" zone. Zones have all sorts of nifty variables, such as gravity, friction, etc etc...basically you can totally change the way a level plays by simply tweaking the zones. In kothZone we use the two functions ActorEntered() and ActorLeaving() to calculate the time spent in the zone, and other that its a normal zone.
// ============================================================
// koth.kothZone
// ============================================================
class kothZone expands ZoneInfo;

// ActorEntered() is called whenever an actor enters the zone
// and we use it here to log the time so that we can calculate
// the total time spent in the zone when the actor leaves.
event ActorEntered( actor Other )
{
// These are just some vars to save us from extra typing :)
 local kothPlayerReplicationInfo kPRI;
local kothBotReplicationInfo kBRI;

// Okay, if they are a player and have the right replication
// info we set the time they entered and set bIsInZone to
// true. The code is the same for bots, except since they
// have a different replication info class than players we
// have to special handle it.
 if (Other.IsA('PlayerPawn'))
{
if (PlayerPawn(Other).PlayerReplicationInfo.IsA('kothPlayerReplicationInfo'))
{
kPRI = kothPlayerReplicationInfo(PlayerPawn(Other).PlayerReplicationInfo);
kPRI.ZoneEnterTime = Level.TimeSeconds;
BroadcastMessage(kPRI.PlayerName$" entered.");
kPRI.bIsInZone = true;
}
} else if (Other.IsA('Bot'))
{
if (Bot(Other).PlayerReplicationInfo.IsA('kothBotReplicationInfo'))
{
kBRI = kothBotReplicationInfo(Bot(Other).PlayerReplicationInfo);
kBRI.ZoneEnterTime = Level.TimeSeconds;

BroadcastMessage(kBRI.PlayerName$" entered.");
kBRI.bIsInZone = true;
}
}

// Always be sure to call the parent's version of the function
// unless we want to break things.
 Super.ActorEntered(Other);
}

// ActorLeaving() is called when an actor leaves the zone, and
// here we calculate the time they spent in the zone and set their
// TotalTime. Note that when a player dies they don't leave the
// zone until they actually respawn, so we have to check for
// death in kothGame so that a player can't just sit and rack
// up kothTime waiting to respawn.
event ActorLeaving( actor Other )
{
local kothPlayerReplicationInfo kPRI;
local kothBotReplicationInfo kBRI;

// If they are a player and have the right replication info
// just add the difference from when they entered and left
// to the total time, and then reset everything. Same code
// for bots, just have to special handle it.
 if (Other.IsA('PlayerPawn'))
{
if (PlayerPawn(Other).PlayerReplicationInfo.IsA('kothPlayerReplicationInfo'))
{
kPRI = kothPlayerReplicationInfo(PlayerPawn(Other).PlayerReplicationInfo);
if (kPRI.ZoneEnterTime != 0)
kPRI.ZoneExitTime = Level.TimeSeconds;
kPRI.TotalTime += kPRI.ZoneExitTime - kPRI.ZoneEnterTime;
kPRI.ZoneExitTime = 0;
kPRI.ZoneEnterTime = 0;
kPRI.bIsInZone = false;
BroadcastMessage(kPRI.PlayerName$" left with "$kPRI.TotalTime$" total time.");
}
}
else if (Other.IsA('Bot'))
{
if (Bot(Other).PlayerReplicationInfo.IsA('kothBotReplicationInfo'))
{
kBRI = kothBotReplicationInfo(Bot(Other).PlayerReplicationInfo);
if (kBRI.ZoneEnterTime != 0)
kBRI.ZoneExitTime = Level.TimeSeconds;
kBRI.TotalTime += kBRI.ZoneExitTime - kBRI.ZoneEnterTime;
kBRI.ZoneExitTime = 0;
kBRI.ZoneEnterTime = 0;
kBRI.bIsInZone = false;
BroadcastMessage(kBRI.PlayerName$" left with "$kBRI.TotalTime$" total time.");
}
}

Super.ActorLeaving(Other);
}

defaultproperties {
}

Unreal/UT uses a seperate class called PlayerReplicationInfo to store some semi-persistent data for each player, seperate from the PlayerPawn class. By subclassing the PRI class you can easily add some variables to the players specific to your modification.
// ============================================================
// koth.kothPlayerReplicationInfo
// ============================================================
class kothPlayerReplicationInfo expands PlayerReplicationInfo;

// These are the new variables we need for KOTH
// TotalTime being the total time tallied after leaving
// the kothZone, ZoneEnterTime is set when we entered
// the zone, and ZoneExitTime is set when we left.
// bIsInZone is just a boolean to determine if we need
// to calculate the latest time in the Hud/Scoreboard,
// or if we can just use TotalTime
var float TotalTime; // in seconds
var float ZoneEnterTime;
var float ZoneExitTime;
var bool bIsInZone;

defaultproperties {
}

The HUD class is called every frame to draw all the nifty things like health, fragcount, etc etc for each player. Ultimately you'll probably want to go through every function in the HUD and customize the entire look for you modification, but since KOTH is a simple mod, we're going to make a simple change to the HUD. :) All we do is change the fragcount from displaying frags to displaying the KOTH Time.
// ============================================================
// koth.kothChallengeHUD
// ============================================================

class kothChallengeHUD expands ChallengeHUD;

// For our HUD all we do is change DrawFragCount()
// to display the kothTime instead of the frags, since
// time is more important than frags. Just a cut and
// paste with a few alterations...
simulated function DrawFragCount(Canvas Canvas)
{
local float Whiten;
local int X,Y, CurrentTime;
local kothPlayerReplicationInfo kPRI;

if ( PawnOwner.PlayerReplicationInfo == None )
return;

// If our owner isn't a kothPlayer then something
// is wrong, so abort! abort! abort! :)
 if ( !PawnOwner.PlayerReplicationInfo.IsA('kothPlayerReplicationInfo') )
return;

// CurrentTime is calculated by taking the TotalTime,
// and then if the player is in a koth Zone, it determines
// the latest time.
 kPRI = kothPlayerReplicationInfo(PawnOwner.PlayerReplicationInfo);
CurrentTime = kPRI.TotalTime;
if (kPRI.bIsInZone)
CurrentTime += Level.TimeSeconds - kPRI.ZoneEnterTime;

Canvas.Style = Style;
if ( bHideAllWeapons || (HudScale * WeaponScale * Canvas.ClipX <=
Canvas.clipx - 256 * scale) )
y = Canvas.clipy - 63.5 * scale;
else
y = Canvas.clipy - 127.5 * scale;
if ( bhideallweapons )
x = 0.5 * Canvas.clipx - 256 * scale;
Canvas.curx = x;
Canvas.cury = y;
Canvas.drawcolor = hudcolor;
whiten = level.timeseconds - scoretime;
if ( whiten < 3.0 )
{
if ( hudcolor == goldcolor )
Canvas.drawcolor = whitecolor;
else
Canvas.drawcolor = goldcolor;
if ( level.bhighdetailmode )
{
Canvas.curx = x - 64 * scale;
Canvas.cury = y - 32 * scale;
Canvas.style = erenderstyle.sty_translucent;
Canvas.drawtile(texture'botpack.hudweapons', 256 * scale, 128 * scale, 0, 128, 256.0, 128.0);
}
Canvas.curx = x;
Canvas.cury = y;
whiten = 4 * whiten - int(4 * whiten);
Canvas.drawcolor = Canvas.drawcolor + (hudcolor - Canvas.drawcolor) * whiten;
}

Canvas.drawtile(texture'botpack.hudelements1', 128*scale, 64*scale, 0, 128, 128.0, 64.0);
Canvas.drawcolor = whitecolor;

// normally it would draw the frag count right here, but
// we just alter it to draw the time, and all is good.
 drawbignum(Canvas, currenttime, x + 40 * scale, y + 16 * scale);
}

defaultproperties {
}

We make pretty much the same change to the Scoreboard as we did to the HUD, just changing frags to KOTH time. Again you'll probably want to go through all the functions and customize the Scoreboard specific to your mod.

// ============================================================
// koth.kothscoreboard
// ============================================================

class kothscoreboard expands tournamentscoreboard;

// We're going to change drawcategoryheaders() to only draw
// koth time, and not frags/deaths/etc.
function drawcategoryheaders(Canvas Canvas)
{
  local float offset, xl, yl;

  offset = Canvas.cury;
  Canvas.drawcolor = whitecolor;

  Canvas.strlen(playerstring, xl, yl);
  Canvas.setpos((Canvas.clipx / 8)*2 - xl/2, offset);
  Canvas.drawtext(playerstring);

  Canvas.strlen("KOTH Time", xl, yl);
  Canvas.setpos((Canvas.clipx / 8)*5 - xl/2, offset);
  Canvas.drawtext("KOTH Time");

}

// Also need to adjust drawnameandping to draw koth time instead
// of frags and deaths, etc.  Note this is mainly just a cut
// and paste of the tournament scoreboard, I didn't really see
// the need to make a brand new scoreboard, just change the
// existing one slightly to fit our needs.
function DrawNameandPing(Canvas Canvas, PlayerReplicationInfo pri, float xOffset, float yOffset)
{
  local float xl, yl, xl2, yl2, xl3, yl3;
  local font Canvasfont;
  local bool blocalplayer;
  local playerpawn playerowner;
  local int time, kothtime;
  local kothplayerreplicationinfo kpri;
  local kothbotreplicationinfo kbri;

  playerowner = playerpawn(owner);

  bLocalPlayer = (pri.playername == playerowner.playerreplicationinfo.playername);
  Canvas.font = myfonts.getbigfont(Canvas.Clipx);

  // Draw name
  if ( pri.badmin )
    Canvas.Drawcolor = whitecolor;
  else if ( blocalplayer )
    Canvas.Drawcolor = goldcolor;
  else
    Canvas.Drawcolor = cyancolor;

  Canvas.setpos(Canvas.Clipx * 0.1875, yoffset);
  Canvas.Drawtext(pri.playername, false);

  Canvas.strlen( "0000", xl, yl );

  // Draw score
  if ( !blocalplayer )
    Canvas.Drawcolor = lightcyancolor;

        // here is where we determine the up-to-date time
        // to display, and just replace what used to Draw
        // the score with our up-to-date time. :)
  if (pri.isa('kothplayerreplicationinfo'))
  {
    kpri = kothplayerreplicationinfo(pri);
    kothtime = kpri.totaltime;
    if (kpri.bisinzone)
      kothtime += level.timeseconds - kpri.zoneentertime;
  }
  else if (pri.isa('kothbotreplicationinfo'))
  {
    kbri = kothbotreplicationinfo(pri);
    kothtime = kbri.totaltime;
    if (kbri.bisinzone)
      kothtime += level.timeseconds - kbri.zoneentertime;
  }

  Canvas.Strlen( kothtime, xl2, yl );
  Canvas.Setpos( Canvas.Clipx * 0.625 + xl * 0.5 - xl2, yoffset );
  Canvas.Drawtext( kothtime, false );

  if ( (Canvas.Clipx > 512) && (Level.NetMode != NM_Standalone) )
  {
    Canvas.DrawColor = WhiteColor;
    Canvas.Font = MyFonts.GetSmallestFont(Canvas.ClipX);

    // Draw Time
    Time = Max(1, (Level.TimeSeconds + PlayerOwner.PlayerReplicationInfo.StartTime - PRI.StartTime)/60);
    Canvas.TextSize( TimeString$": 999", XL3, YL3 );
    Canvas.SetPos( Canvas.ClipX * 0.75 + XL, YOffset );
    Canvas.DrawText( TimeString$":"@Time, false );

    // Draw FPH
    Canvas.TextSize( FPHString$": 999", XL2, YL2 );
    Canvas.SetPos( Canvas.ClipX * 0.75 + XL, YOffset + 0.5 * YL );
    Canvas.DrawText( FPHString$": "@int(60 * PRI.Score/Time), false );

    XL3 = FMax(XL3, XL2);
    // Draw Ping
    Canvas.SetPos( Canvas.ClipX * 0.75 + XL + XL3 + 16, YOffset );
    Canvas.DrawText( PingString$":"@PRI.Ping, false );

    // Draw Packetloss
    Canvas.SetPos( Canvas.ClipX * 0.75 + XL + XL3 + 16, YOffset + 0.5 * YL );
    Canvas.DrawText( LossString$":"@PRI.PacketLoss$"%", false );
  }
}

defaultproperties {
}


Linked Lists Part 1

by UsAaR33

usaar33@yahoo.com

UsAaR33's mods

This tutorial assumes you have read and understood the UnrealScript language reference by Tim Sweeney (http://unreal.epicgames.com/unrealscript.htm)

Linked list????

A linked list is precisely that; a list of objects linked together by a series of pointers to another object in that list. This allows for a near unlimited amount of objects to be connected; a worthy substitution for dynamic arrays (arrays of no defined size), which are not present in UnrealScript. This can be used for a variety of purposes; a player's inventory a history of messages, a bunch of pipebombs a player can detonate, or even simply have easier and quicker access to certain actors.

How a list is set up

A linked list requires two parts. A "base object" (note that this part, under strange circumstances, may be omitted) which has a pointer a member of the list (for the purpose of this tutorial: the first) and a pointer in EVERY list element to another element.

Class ListElement expands object;
Var ListElement Next; // the next list element.

Class SomeImportantActor expands actor;
Var ListElement ListElement; // the first element in the list

SomeImportantActor should be some critical actor in your mod. As an example, Unreal uses the LevelInfo to hold the pointer to the first Pawn and NavigationPoint in the PawnList and NavigationPointList, respectfully. The first inventory item of a player is connected by a pointer residing inside of that player. The Next pointer points to the next element of the list. The list terminates when Next==None.
A third part of the list also exists; contents. This is simply whatever the list elements are supposed to do or store.

Navigating through a list

The easiest to move through the list is simply to use the For loop.

// this is run inside the SomeImportantActor class.
Local ListElement Element;
For (Element=ListElement; Element!=none; Element=Element.Next)
//here each element's variables can be read, edited, or have functions called on it.

Note how the above works. First the temporary Element pointer is set to the base element. At the end of each loop, the Element pointer is set to its Next pointer. This continues until no more elements are present (i.e. the Element pointer equals None).

Adding to Lists

There are three ways of adding to a list; at the beginning, at the end, or in the middle.
Note: In this example the ListElement class is only an object, but not an actor. If you make a subclass of actor then you should replace new (none) class'ListElement'; with spawn (class'ListElement');

Beginning:
Simply instantiate an object, set its Next pointer to the current base (the ListElement pointer), and then set it as the base:

TempElement=New (none) class'ListElement';
TempElement.next=ListElement;
ListElement=TempElement;

End:
There are two ways that a new element can be added at the end of a list.
The loop method inside the SomeImportantActor:

Local ListElement Element;
Element=ListElement;
While (Element.next!=none)
Element=Element.next;
Element.Next=new (none) class'ListElement';

Note that this loop terminates not when Element is none, but when an Element's next pointer is none. This allows a pointer to the last element of the list to exist when the loop has completed.

The "1337 function in each element" method:
I do not know of the "official" name of this method. Nonetheless, this is the simpler method, which is used to add mutators. Remember that list elements are true objects and CAN have functions called on them. This allows for very simple code to exist.
Inside SomeImportantActor:

ListElement.AddElement(new (none) class'ListElement');

The class ListElement has the following function:

Function AddElement (ListElement NewElement)
{
If (Next!=None)
Next.AddElement(NewElement);
Else
Next=NewElement;
}

First a ListElement is instantiated. Then the ListElement's AddElement function is called with a pointer to the new ListElement. If there is another element in the list, it then calls the AddElement function on that element. Eventually, the end of the list is reached, where Next is none. Now Next is set to point to the new ListElement.

In the middle:
Adding an element into the middle of any list obviously requires a pointer to the item one wishes to add after.
Assume that Element is some element inside the list:

TempElement=new class'listelement';
TempElement.Next=Element.Next;
Element.Next=TempElement;

Again an element is created. Its Next var is set to whatever the Next var is of the element that this one is being added in front of. Finally, the element that is going to have the new element added after it has its Next var set to the new element.

Removing Items:

In the case of actor lists, it is not safe to simply destroy an actor that is part of the list (objects do not apply as they cannot be manually destroyed). This causes any list elements after it to become unlinked. To remove any list item (it is safe to do this in actor.destroyed()), one must do the following:

// in the SomeImportantActor class
Function RemoveElement(ListElement Element)
{
Local ListElement List;
If (Element==ListElement)
Element=ListElement.Next;
Else
For (List=Element;List!=none;List=List.Next)
If (List.Next==Element)
{
List.Next=Element.Next;
Break;
}
}

First and foremost, a check must be performed to see if the element to be removed is the base pointer. If it is, then the base is simply set to whatever that element's next is. Yet, if this is not the case, the code must go looking for that doomed object. A loop is performed which goes through all the elements. With each loop, it is checked temporary List pointer's Next pointer is the item that should be removed. If this is the case, that element's next pointer is set to the to-be-deleted element's next. The loop can then be terminated.

You can synthesize the above information to conduct some exciting list manipulation. For instance to move a list item, you can simply remove it and then insert it in the middle of something else.

Advanced Lists

The above is only the basics of how a list is constructed. Many other pointers however may exist in a list. For instance, a two-way list can be created by having each item not only have a pointer to the next, but also to the previous. There can also be a pointer in every element to the base or even to the end. While this does mean execution can be faster and frankly easier to set up, it does mean more needs to be done when adding or removing elements. Also note that more pointers allow greater flexibility. For instance, with a pointer to the first or previous element, this allows for the link to the list to be at any element, rather than the first. As an example, in Operation: Na Pali, the translator has a history of all previous messages. I simply have a pointer to the TranslatorHistoryList that holds the current message. If a user wishes to read older or newer messages, the pointer to the TranslatorHistoryList simply changes to the current pointer's Next or Prev pointers, respectfully. This allows for simple and fast executing code.
Note: When variables exist that apply to the list as a whole, rather than a per element basis, they should be placed in the actor that links to the list or the first element. In the latter case, this often means having a pointer to the first element in all elements.

Existing Lists in Unreal Tournament

This part of the tutorial explains existing linked lists in Unreal Tournament.
Actor list
Type of List
All actors in Unreal are connected though a gigantic list (well it is actually a dynamic array, but to make life easier think of it as a list) that exists only in the native c++ code. Without this list, actors would be just plain old objects. The base of this "list" is actually the native level object (all actors have a pointer to this: Xlevel)
Exists: On both client and server. When a client "receives" an actor, it is added and when its connection is closed (except with bnettemporary), it is removed.
Adding to List: Spawning an actor automatically does this. It adds at the end of the list. Note that levelinfo is always the first actor.
Removing from List: Destroying an actor automatically does this.
Navigating the list: In the actor class, various "interators" exist. These allow you read the list in different ways. Simply use ForEach Interator_Function(params) to use them. ForEach acts much like a For Loop.

AllActors ( class<actor> BaseClass, out actor Actor, optional name MatchTag );

Baseclass is the parent of classes you wish to look for. The actor pointer passed in the second parameter becomes the actor outputted. As the iterator functions are hard-coded into the compiler, you can have the actor pointer be of the BaseClass or any of its parents. Matchtag, if given, will only return actors, which have that tag. This will go through every actor in the level and is thus somewhat slow (this is not noticeable however unless it is called multiple times in one frame), and thus use it sparingly. If a more class specific list exists, such as that for pawns and navigation points (see below), use those instead. Note that if you wish to terminate the loop when a certain actor is returned, simply use break;

ChildActors ( class<actor> BaseClass, out actor Actor );

The paramaters work the same as AllActors'. However, this only returns actors with their owner set to the class this is run on. It has the same speed hit as AllActors.

BasedActors ( class<actor> BaseClass, out actor Actor );

Returns all actors that have this as a base. Same speed hit as AllActors.

TouchingActors( class<actor> BaseClass, out actor Actor );

Returns all actors touching this one. This uses a special "collision hash" and thus is quite fast.

TraceActors ( class<actor> BaseClass, out actor Actor, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, optional vector Extent );

This is supposed to trace a line from Start to End and return all actors hit (executes as fast as a normal trace). However, this is not ever used by Epic in code and I recall of no one ever getting it to work right. I do not recommend using it.

RadiusActors ( class<actor> BaseClass, out actor Actor, float Radius, optional vector Loc );

This returns all actors that are within radius units of Loc (or if it isn't given; then the actor's location). Same speed hit as AllActors().

VisibleActors ( class<actor> BaseClass, out actor Actor, optional float Radius, optional vector Loc );

This is much like RadiusActors() only it also checks if an actor is visible from Loc. Same speed hit as AllActors.

VisibleCollidingActors ( class<actor> BaseClass, out actor Actor, optional float Radius, optional vector Loc, optional bool bIgnoreHidden );

This only returns actors with bCollideActors as true. It uses the collision hash to check, and thus it is much faster than Allactors, in normal circumstances. If a very high radius is used (900 or so), then it becomes very slow, and VisibleActors should be used instead.

ZoneInfo.ZoneActors( class<actor> BaseClass, out actor Actor );

Returns all actors inside that zone. Same speed hit as AllActors(). Go figure.

Inventory List
Type of List: Standard one way linked list.
Notice how it is defined in actor, and not in inventory. This is designed so other actors (pawns) can have a link to the base, while keeping the same pointer name.
Exists: Server. On the client side however, it will only exist for the player being controlled and within his inventory. Other player's will not have an inventory list. Note that in very rare events, replication can come at a weird order and cause the inventory pointer of one item to point to an older one in the list. Thus when using this list client-side, you should have a check so that no more than 100 or so loops occur (to avoid infinite iterators).
Adding to List: Call AddInventory() on the pawn you wish to add that inventory item to with that item in the parameters. It is then added to the beginning of the inventory list. This should only be done server-side. Note that inventory's GiveTo() automatically does this.
Removing From List: Class DeleteInventory() on the pawn(owner) with the item you wish to delete in the parameters. Again, this should only be performed server-side. When an inventory item is destroyed, this automatically occurs (see Inventory.Destroyed()).
Navigating the List: If you are only searching for one item of a certain class (not child classes!), you can simply call FindInventoryType on the pawn who owns the items. Yet to search through the entire list do the following:

Local Inventory Inv;
For (Inv=somepawn.Inventory;Inv!=none;Inv=Inv.Inventory)
//do stuff here

Pawn List
This list is the reason I am writing this tutorial. I tire of seeing code that uses ForEach AllActors(class'pawn',p), when there is a much faster way this can be done.
Type of List: Native controlled standard one way list linked by levelinfo.pawnlist.
Exists: Server Side only at BeginPlay() in gameinfo. Thus, on a client or in a mutator (post/pre)BeginPlay(), you need to stick with AllActors(class'pawn',p)
Adding to List: Simply call AddPawn() on the pawn. Note that pawn automatically does this in its PreBeginPlay() so you really do not need to worry about calling this. Adds to the end of the list.
Removing from List: Call RemovePawn() on the pawn. This is automatically taken care of in Destroyed().
Navigating the List: The list base is located in levelinfo. Simply call (in any actor):

Local pawn p;
For (p=level.pawnlist;p!=none;p=p.nextpawn)
//do stuff

Of course you can add whatever IsA checks and casting you need. (for instance if you are only looking for PlayerPawns, have underneath the For loop If (p.IsA('playerpawn')) )

Navigation Point List
Type of List: Constant standard one way list linked by LevelInfo.NavigationPointList
Exists: Server-side only.
Adding To list: Cannot be done. The list is generated upon building the paths in UnrealEd.
Removing From List: Cannot be done.
Navigating the List: Most likely you will use the navigation point list to find path nodes (a simple navpoint added by level authors). This allows you to spawn actors at many different locations in the map, and still have bots touch them. For instance, the relics mutator searches the Navigation Point list for pathnodes. Relics are then spawned at a random node. Like the pawn list, the base is in levelinfo.

Local NavigationPoint np;
For (np=level.NavigationPointList;np!=none;np=np.nextnavigationpoint)
//do stuff

Note that many other lists exist within navigation point. They are all used exclusively for AI navigation. Unless your name is Pfhoenix, they have no meaning.

Mutator List:
The introduction of mutators in Unreal 2.24 was one of the best things ever done for mod makers. What makes mutators so powerful? The fact that they are linked lists. This allows many different mods to be run at once and change many different game elements.
There are in fact 4 mutator lists in Unreal Tournament; the primary mutator list, damage mutators that only affect (Mutator)TakeDamage calls, message mutators that only affect messages (broadcast, broadcastlocalized, and player's talking), and finally HUD mutators that allow mutators to draw on the HUD.
Type of List: All are standard one-way linked lists. HUD mutators are linked to by a HUD, and all others are linked by the gameinfo.
Exists: Mutators normally (default) only exist server-side. However, the HUD mutators must be on the client (see below).
Adding to List:
Normal mutators:
When a user selects start, UT opens a map with a special parameter:
?mutator=MutatorPackage.MutatorClass, AnotherMutatorPackage.AnotherMutatorClass

The GameInfo's InitGame() is called when it is first spawned. First the Base Mutator (generally DmMutator) is spawned. From there the mutator options are parsed (this tutorial is not about string manipulation and Unreal URLs!), the mutator class dynamically loaded, then spawned, then finally added to the list:

log("Add mutator "$LeftOpt);
MClass = class<Mutator>(DynamicLoadObject(LeftOpt, class'Class'));
BaseMutator.AddMutator(Spawn(MClass));

AddMutator() adds to the end of the list with the "1337 function" method described earlier in this tutorial. Now the mutator list is ready to receive notification of actor spawning, mutate commands, player respawnings, death notifications, and all those other wonderful events mutators receive from pawns and, more commonly, the gameinfo.

DamageMutators:
To make a mutator be used as a damage mutator (it still has normal mutator functions!), simply call level.game.RegisterDamageMutator(MutatorToBeRegistered) The mutator will now receive notification whenever a pawn takes damage and can modify certain values.

MessageMutators:
This is another specialized mutator, not unlike a damage mutator. Simply call level.game.RegisterMessageMutator(MutatorToBeRegistered) to be able to edit all of the wonderful messages. Incidentally, message mutators did not exist until UT version 4.13. They were created simply for support of Rocket Arena. They have also been beneficial in stopping message hacking. :p

HudMutators:
I cannot even count the amount of times people have why their HUD mutator will not work in network play. What is the reason for this problem? It is quite simple; mutators exist only on the server, yet HUDS are client-side only. Epic's code makes it appear that you can simply call RegisterHUDMutator, which is untrue. The following is one way of adding a HudMutator on the client:

Step 1: In the default properties of your mutator, place the following:

bAlwaysRelevant=True
bNetTemporary=True
RemoteRole=Role_SimulatedProxy

These values cause the mutator to be replicated to all clients, but the connection only stays open until the client has received the mutator. The mutator must also be a Simulated Proxy on the client for step 2 to work.
Step 2: Now add the following code to your mutator:

Simulated Function Tick(float delta)
{
If (level.netmode==NM_DedicatedServer||bHUDMutator)
Disable('Tick');
Else
RegisterHUDMutator();
}

Each frame, RegisterHUDMutator() is called. If it finds a PlayerPawn with a HUD (local player!), it will set that HUD's HUDMutator to this mutator (as well as preserve the list) and set bHUDMutator to true. If the mutator has already been registered or this is a dedicated server (no HUDs!), then tick () can be safely disabled.

On a final note, I ask that all mod makers who make use of HUDMutators to do the following:
At the end of PostRender() in your HUDmutator, PLEASE add:

If (NextHUDMutator!=none)
NextHUDMutator.PostRender(canvas);

For some dumb reason, Epic did not add that support to begin with. Without those lines, your mutator will be the only HUDmutator used. Other HUDMutators will not receive PostRender() calls, and thus not be able to display anything on screen.

Removing from List:
No specialized functions exist to remove elements from mutator lists. Simply follow the removal model at the beginning of this tutorial.

Navigating the List:
Rarely will you ever need to iterate through the mutator list. All functions of mutators simply call that same function on the next mutator, returning a result if necessary. Yet if you wish to go through all mutators simply use:

Local mutator m;
For (m=level.game.Xmutator;m!=none;m=m.nextYmutator)
//do stuff

For normal mutator list:
Replace the capital X with base and blank out the capital Y.
Damage mutators:
X=Damage, Y=Damage
Message Mutators:
X=Message, Y=Message
HUD mutators:
Replace level.game.Xmutator with SomePlayerPawnPointer.myhud.HUDMutator and Y with HUD.

Spawn Notification List
This is a list of very powerful actors; SpawnNotifies. For more information read http://unreal.epicgames.com/UTMagic.html. Whenever an actor is spawned/received on a client, native code calls SpawnNotification(actor) on the LevelInfo.SpawnNotify
List Type: Standard one-way list linked by levelinfo.SpawnNotify.
Exists: Server and client-side. Note however that SpawnNotifies manually add themselves on both server and client, rather than having the list replicated, as is the case with inventory.
Adding to the List:
SpawnNotify.PostBeginPlay() automatically adds to the beginning of the list.
Removing from the List:
SpawnNotify.Destroyed() automatically removes that SpawnNotify. Feel free to call Destroyed() yourself to remove a SpawnNotify from a list, for this does not actually destroy the actor.

Note: The entire spawn notification system can be temporary deactivated as follows:

Local SpawnNotify Sn;
Sn=level.SpawnNotify;
Level.SpawnNotify=None;
//do stuff here without worrying about Spawn Notifies.
Level.SpawnNotify=Sn;

Other cases of Linked Lists

InterpolationPoint: Uses a two-way list for interpolation of player locations and other properties between each point. While the list is created in unrealscript, that is as far as unrealscript handles it. Everything else is handled by native code.

Pbolt: Uses a standard one-way list that you will probably never need to touch. The plasma beam you see when alt firing the Pulse Gun is actually a linked list of Pbolt's. Unfortunately, the system wasn't written in the best way possible. Ideally, there should be a pointer to the StarterBolt in all beams. Variables only important to the beam as a whole (AccumulatedDamage, LastHitTime) are controlled in each beam, rather than only the list base. Thus when beams are destroyed, some of those values are lost, resulting in odd damage patterns.

Mover: Uses a one-way linked list that also has a pointer to the base. This is used for movers that follow other movers. Feel free to explore this code on your own.

Actor.Deleted: A list of actors that have been deleted and are awaiting garbage collection. This occurs when 128 actors are in the list. This is only used in Epic's native c++ code.

SavedMove: For player movement in a network environment, the client must save old moves to be sent later (to avoid overflowing the network and in cases of packet loss). The actual list is the standard one-way one, which carries move information. A playerpawn has pointers to the SavedMoves (the beginning of the SaveMove list), FreeMoves (a move that is "free"), and PendingMove (the next move to be sent to the server). Yet, this is a tutorial on lists, not something else. Study the SavedMove class and playerpawn.ReplicateMove() to learn more.

Menu.ParentMenu: This is simply a pointer to the previous green menu that showed. These "green menus" were used in Unreal I only. There is little need to understand how they work if you script in UT.

ListElement: This is a two-way list that was set up for use with the WebAdmin. It is a quite powerful method of storing data.

UwindowList: This is a very advanced list, which stores various data for the uWindow system.

UwindowWindow: All the menus seen in UT are actually stored with this complex list system.


Locational Damage

by crack_addict

Alright, here's the idea: a sniper rifle that knows what part of the body its hitting. How do we do this? Well to explain I simply subclassed UT's sniper rifle and replaced the ProcessTraceHit() function, which if you've done anything with Weapons yet, you'll know that this is where damage is applied and shells are normally spawned and whatnot.

For clarity's sake, I've omitted everything but the location detection code. Hopefully this will make things easier to understand on your end. Note that there is more than one way to accomplish this goal, probably more efficient and tons smaller, but I've decided to use rotators since I think angles are easier to understand vector dot products. :) Note that this is meant for humanoids, ie the code assumes the head is located above the body and legs, etc etc.
class BetterSniperRifle extends SniperRifle;

function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z)
{
// We'll use two variables to store some data, not necessary but
// it definitely helps to keep code clearer and cleaner.
 local int HitHeight, HitAngle;

// First off, lets make sure its a pawn, cause most rocks aren't
// worth the trouble to do locational damage (thats a joke...)
 if (Other.IsA('Pawn'))
{
// Okay HitHeight is easy to get, we simply take the Z point
// (z being the vertical axis) where the bullet hit and subtract
// that from the target's location. (which will be the middle
// of the model)
 HitHeight = HitLocation.Z - Other.Location.Z;

// Getting HitAngle is a bit more complicated to understand,
// but here goes: Basically we convert where the bullet hit
// into a direction, and subtract that from the direction the
// target is facing. This will let us tell what area the bullet
// hit, sort of determining what quadrant it is in (remember
// trig?)
 HitAngle = (Other.Rotation.Yaw - rotator(HitLocation - Other.Location).Yaw) & 65535;

// BroadcastMessage is your friend. Use it to send useful
// debug information in game, just be sure to remove it once
// you want to release your code :)
 BroadcastMessage("HitHeight: "$HitHeight$", HitAngle: "$HitAngle$", Other.Rotation: "$Other.Rotation);

// Each actor that has collision has two variables to define
// its area of collision, CollisionHeight and CollisionRadius.
// UT uses this info to generate a cylinder of collision, and
// here we use CollisionHeight to determine what part of the
// model we hit, as the upper part will most likely be the "head"
// while the middle the "body" and the bottom the "legs".
 if (HitHeight > 0.62 * Other.CollisionHeight)
BroadcastMessage("Head hit");
else if (HitHeight < 0.35 * Other.CollisionHeight)
BroadcastMessage("Leg hit");
else BroadcastMessage("Body hit");

// This is where we classify the angle into our "quadrants",
// but instead of using right (90 degree) angles to define
// the quadrants, i used 12000 UUs, or about 70 degrees or so.
// This will give us 4 offsized quadrants, with 2 big ones
// for front and rear, and 2 small ones for the sides.
// The logic here is simple, if the angle is within our bounds
// then it should be classified in the appropriate "quandrant",
// otherwise check the next bounds and so on.
// See the image below for a clearer picture.
 if ( (HitAngle < 12000 && HitAngle > 0) || (HitAngle > 53535 && HitAngle < 65535) )
BroadcastMessage("Frontal hit");
else if ( (HitAngle < 44768 && HitAngle > 20768) )
BroadcastMessage("Rear hit");
else BroadcastMessage("Side hit");
}
}

Now at this point it would be a good idea to do add some damage code, and maybe some effects like slowing the player down when hit in the legs...etc. Make this locational detection code actually useful for something, but alas thats beyond the scope of this tutorial, or some other lame excuse like that... :)


Making a Relic

by crack_addict

Relics are mutators that offer various effects through an inventory item which is given to the player when he runs over it. To show how to make a new relic I'll just run through the Blink relic which I made, basically it just toggles the player from being visible/invisible..."blinking" in and out. Simple stuff really.

For a relic there are only 2 classes you need, the relic class itself which handles the spawning of the second class, an inventory pickup. In this case we use RelicBlink and RelicBlinkInventory. Before you make your own relic, its always a good idea to check out the Relic and RelicInventory classes, and a couple of the other relics...just to help you get a good handle on whats going on. Also if you haven't played with mutators yet, you should take a look at them as well, since Relic is just a glorified mutator. :)

//=====================================================
// RelicBlink.
//=====================================================
 class RelicBlink expands Relic;

defaultproperties
{
RelicClass=Class'grelics.RelicBlinkInventory'
}

Simple, eh? Fortunately the Relic class handles all the spawning and whatnot, so all we have to do is tell it the class we want it to spawn, in this case 'grelics.RelicBlinkInventory'. Now on to the actual meat of a relic...
//=====================================================
// RelicBlinkInventory
//
// Toggles visibility/invisibility by spawning/destroying
// invisibility items for the player.
//=====================================================
 class RelicBlinkInventory expands RelicInventory;

#exec MESH IMPORT MESH=blink ANIVFILE=MODELS\blink_a.3d DATAFILE=MODELS\blink_d.3d X=0 Y=0 Z=0
#exec MESH ORIGIN MESH=blink X=0 Y=0 Z=0

#exec MESH SEQUENCE MESH=blink SEQ=All STARTFRAME=0 NUMFRAMES=1
#exec MESH SEQUENCE MESH=blink SEQ=blink STARTFRAME=0 NUMFRAMES=1

#exec TEXTURE IMPORT NAME=blink_skin FILE=TEXTURES\blink_skin2.pcx GROUP=Skins FLAGS=2

#exec MESHMAP NEW MESHMAP=blink MESH=blink
#exec MESHMAP SCALE MESHMAP=blink X=0.1 Y=0.1 Z=0.2

#exec MESHMAP SETTEXTURE MESHMAP=blink NUM=0 TEXTURE=blink_skin

// Is the player invisible?
var bool bIsInvis;

// Makeinvis() - creates an invisibility object and gives it to the
// player (grelics.BlinkItem)
function MakeInvis()
{
local BlinkItem invis;

// All we do here is spawn an invisiblity item (BlinkItem in this case),
// set some properties and then give to the player using the GiveTo()
// function.
 invis = Spawn(class'grelics.BlinkItem');
invis.Charge = 500;
invis.bHeldItem = true;
invis.RespawnTime = 0.0;
invis.GiveTo(Pawn(Owner));
invis.Activate();

// Set invis to true and then use the SetTimer function to be called
// in 5.0 seconds so that we can make the player visible
 bIsInvis = true;
SetTimer(5.0, true);
}

// MakeVis() - finds the invis item and removes it from the player
function MakeVis()
{
local Inventory invis;

// This is the exact opposite of MakeInvis(). Here we use the
// FindInventoryType() function from the Pawn class to see if the
// player has an invis item. If they do then we deactivate it
// and send it off into oblivion...
 invis = Pawn(Owner).FindInventoryType(class'grelics.BlinkItem');
if (invis != NONE)
{
Pickup(invis).UsedUp();
Pawn(Owner).DeleteInventory(invis);
invis.Destroy();
}

// Then set the timer to be called in a second to make then invis
// again.
 SetTimer(1.0, true);
bIsInvis = false;
}

// When the relic is picked up, the relic goes into the Activated state,
// so we put some code here to start the whole vis/invis process, and
// also here is where we define the Timer function so that we can toggle
state Activated
{
function Timer()
{
if (bIsInvis)
MakeVis();
else MakeInvis();
}

Begin:
MakeInvis();
bIsInvis = true;
SetTimer(5.0, true);
}

defaultproperties
{
PickupMessage="You picked up the blink relic."
PickupViewMesh=Mesh'grelics.blink'
PickupViewScale=0.600000
Icon=Texture'relics.Icons.RelicIconRedemption'
Physics=PHYS_Rotating
Skin=Texture'grelics.Skins.blink_skin'
CollisionHeight=40.000000
}

Thats pretty much it, in case you're wondering, BlinkItem is just a subclass of UT_Invisibility that just doesn't send the "Invisibility has worn off..." message. Oh, one last thing, for all mutators (and thus relics), you must have an int file detailing your classes if you want them to show up in UT's menus. Here's the grelics package int file (grelics.int) with the Blink relic statement.

[Public]
Object=(Name=grelics.RelicBlink,Class=Class,MetaClass=Engine.Mutator,
Description="Relic: Blink,A magical relic that causes the owner to blink in and out of visibility.")

Again, pretty simple. Just a quick line describing the relic, with a short description. Just make one for you package (blah.int, sexy.int...etc) and stick it in UT/system with the package and your relic should show up in the mutators menu. If you have more than one relic in a package, just add another line... :)


Melee Weapons

by Mr. Self-destruct

The scope of this tutorial is to provide an overview to the various techniques which can be used to locate target(s) for a melee weapon, demonstrate their usage and discuss the disadvantages of each technique. Also, the assumption is that you are familiar enough with UnrealScript to be able to create your own weapons, (if you aren't go read one of the tutorials on Chimeric).

TraceShot

The TraceShot function lets us trace along a line in 3D space to see whether it intersects an object. This approach is used by all "instant hit" weapons and the chain saw in Unreal Tournament, and happens to be the simplest method.

actor TraceShot( out vector HitLoc, out vector HitNorm, vector End, vector Start ); Returns the first actor touched by the line traced from the Start point to the End point. HitLoc is set to the hit location and HitNorm is set to an outward-pointing hit normal.

Because it is only possible to "hit" one target this makes it unsuitable for weapons where you'd like to be able to hit several things at once, also it requires a high degree of accuracy on the users part.

Below is a demonstration of using TraceShot:

// This code assumes it's part of a Weapon class
function MeleeTargetting()
{
local vector HitLoc, HitNorm, End, X, Y, Z, Start;
local actor Other;

// Get vectors for where the player is aiming on each axis
GetAxes(Pawn(Owner).ViewRotation, X, Y, Z);
// Calculate starting location
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X
+ FireOffset.Y * Y + FireOffset.Z * Z;
AdjustedAim = Pawn(Owner).AdjustAim(1000000, Start, AimError, False, False);
// Using an arbitrary range of 100 UUs
End = Owner.Location + (100 * vector(AdjustedAim));
Other = Pawn(Owner).TraceShot(HitLoc, HitNorm, End, Start);
// Insert code to deal damage, spawn effects etc. here
}

TraceActors

To directly quote the UnrealScript Language Reference:

TraceActors( class BaseClass, out actor Actor, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, option vector Extent ); Iterates through all actors which touch a line traced from the Start point to the End point, using a box of collision extent Extent. On each iteration HitLoc is set to the hit location and HitNorm is set to an outward-pointing hit normal.

So we have the capability to check what intersects a definable cuboid:
// This code assumes it's part of a Weapon class
function MeleeTargetting()
{
local vector HitLoc, HitNorm, End, X, Y, Z, Start;
local actor Other;

// Get vectors for where the player is aiming on each axis
GetAxes(Pawn(Owner).ViewRotation, X, Y, Z);
// Calculate starting location
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X
+ FireOffset.Y * Y + FireOffset.Z * Z;
AdjustedAim = Pawn(Owner).AdjustAim(1000000, Start, AimError, False, False);
// Using an arbitrary range of 100 UUs
End = Owner.Location + (100 * vector(AdjustedAim));
// Using TraceActors and a 10x10x10 cube for the extents
foreach TraceActors(class'Actor', Other, HitLoc, HitNorm,
End, Start, vect(10.0, 10.0, 10.0)
{
// Insert code to deal damage, spawn effects etc. here
}
}

Of the three techniques in this tutorial, I would have to say that I feel TraceActors is the best one. The main limitation is that the Extent can only be a cuboid, and for example you may want to use an arc.

VisibleActors & Dot Product

Again quoting the UnrealScript Language Reference:

VisibleActors( class BaseClas, out actor Actor, optional float Radius, optional vector Loc ); Iterates through a list of all actors who are visible to the specified location (or if no location is specified, this actor's location).

VisibleActors will iterate through a list of all visible actors within a specified radius, but we only want to deal actors who're within a specific area in front of the player. So we use dot product to calculate the angle between where the player is aiming and where each actor is located. Effectively we can filter out all actors apart from those who lie in a definable arc in front of the player:
// This code assumes it's part of a Weapon class
function MeleeTargetting()
{
local vector HitLoc, HitNorm, End, X, Y, Z, Start;
local actor Other;

// Get vectors for where the player is aiming on each axis
GetAxes(Pawn(Owner).ViewRotation, X, Y, Z);
// Iterate through all actors within 100 UUs of the player
foreach VisibleActors(class'Actor', Other, 100.0, Owner.Location)
{
// Only deal with actor's within the ~45 degrees in front of the player
if (normal(X) dot normal(Other.Location - Owner.Location) >= 0.7)
{
// Calculate the hit location
HitLoc = Other.Location + (Other.Location - Owner.Location)
* Other.CollisionRadius;
// Insert code to deal damage, spawn effects etc. here
}
}
}

VisibleActors & Dot Product is the most complicated technique of the three and has a distinct disadvantage. The problem is that HitLoc.Z always equals Other.Location.Z, so it's impossible to have head shot detection. The main benefit of this technique is that it affects an arc, as would sweeping a great big axe in front of you.


Messaging

by neural9

Messages are so fundementally important to good persona games that no mod should ever be without. This simple tutorial covers the basics of sending messages to players in the game. As a note, please realise that there are other and more simpler ways to do the functions explained in this tutorial. The point of this tutorial is to examine objects in the game so that a good understanding of how things work is elicited. Some 'other' methods are discussed at the end.

There are several reasons you would want to send messages to people in the game. Firstly, chatting to others enhances the experience. Messages to everyone, messaging to your team in a CTF or TF game, or perhaps personal messages to individual players. Secondly, many events that happen in the game require other players to be notified. Capturing a flag, dying or camping may be some examples.

Whatever your particular requirements are, there are three modes of messaging; all, team & individual. By examing how these functions work, we can modify the code to suit any purpose.

Broadcasting

Broadcasting is sending a message to everyone in the current level. The code to do this (stolen from the actor class in the Unreal source) is :
function BroadcastMessage( coerce string[240] Msg, bool bBeep )
{
local Pawn P;

if ( Level.Game.AllowsBroadcast(self, Len(Msg)) )
{
for( P=Level.PawnList; P!=None; P=P.nextPawn )
if( P.bIsPlayer )
P.ClientMessage( Msg );
}
}

What this function actually does is accept a message string and a boolean variable. It then cycles trough all of the pawns in the level, as it comes across one which is actually a player it calls the method of the pawn to display a message on their screen.

The main body of the code starts with an IF statement. The if statement actually references the 'Level' object which in turn has a 'Game' object which in turn has a method which is called AllowsBroadcast(). The AllowsBroadcast takes two parameters, the object which is calling it, and the length of the message.

If the game does allow broadcasting, i.e. it returns true, the code starts it's 'for' cycle. The 'for' loop utilizes a 'level' object list called 'PawnList'. This maintains all current pawns in the game. Remember though, that all objects in the game are pawns, not just the human players, so we need some way of checking if the pawns we're referencing are human.

Well, we're in luck. Each pawn has a boolean property called 'bIsPlayer' which is set by the engine when a pawn is created. To cycle through the list, call the 'nextPawn' method of the current pawn. If the pawn is a player, then calling the pawn's 'ClientMessage' method will send the passed parameter (the message) to the actual client machine.

Messaging Individuals

Sending a message to individuals is similar to broadcasting. Sort of selective broadcasting you could say. Using the code :
function MessageIndividual( coerce string[240] Msg, bool bBeep, string[20] sName)
{
local Pawn P;

if ( Level.Game.AllowsBroadcast(self, Len(Msg)) )
for( P=Level.PawnList; P!=None; P=P.nextPawn )
if( P.bIsPlayer && P.playername == sName)
P.ClientMessage( Msg );
}

The code to send individual messages differs only in adding an extra parameter to the function (which we have called by a different name) and adding an extra condition to the final IF statement. All we have done is added a reference to the name of the player, and ensuring that when we cycle through the pawns, we check that we we find a player, his or her name is the same one that is passed to the function.

If you're wondering how to get the name of the player you want to send the messages to, it all depends on how you want to call the function. For example, you could create a new console command of 'TELL', taking two parameters, the name of the player and the message. i.e.

'tell neural9 Your mod sucks, dude!'

Alternatively, you could attach the function to various events & other functions in the game code itself. For example, if you wanted to send the player who bumps into you a message, you could use the 'actor' objects' 'touch' function like this :

function Touch( actor Other )
{
 MessageIndividual( "Stop bumping into me you geek !", true, other.name );
}

You could use the same method of selective broadcasting to send messages to teams in capture the flag or team fortress games. When you create a team actor object, you would have to add a 'teamname' property. By modifying the MesssageIndividual function to accept a teamname rather than a playername, you could select players to send the message to.


The Mutator Class

by Pfoenix

Pfhoenix

mod exemplar

The Mutator class extends the Info class. The following are all the variables (and their purposes that I've discerned) and function members and their purposes (that I've discerned).

Variable members :

var Mutator NextMutator | This is the next generic mutator object in the list of generic mutators
var Mutator NextDamageMutator | This is the next damage mutator object in the list of damage mutators
var Mutator NextHUDMutator | This is the next HUD mutator object in the list of HUD mutators
var bool bHUDMutator | This bool is a flag for whether or not the mutator is a HUDMutator
var class<Weapon> DefaultWeapon | Not sure exactly what this is good for, but an educated guess leads me to believe that if set, this var will override any other set default weapon for the level/game (via MutatedDefaultWeapon() and MyDefaultWeapon(), of which I've never used either)

Function members :

event PreBeginPlay() | This is called before gameplay starts.
simulated event PostRender(canvas Canvas) | Called every tick of gameplay *on the machine which starts this mutator* - i.e. this is will not work over network play. See below for further information on HUD mutators.
function ModifyPlayer(Pawn Other) | Called whenever a player joins the game. Other references the player's pawn object
function ScoreKill(Pawn Killer, Pawn Other) | If a kill is made, this function is called, passing a reference to the Killer (person who scored) and Other (the victim who died). Note - this function is called right on the tick of the kill, before any rendering or other processing has taken place.
function Class<Weapon> MutatedDefaultWeapon() | Returns the default weapon taking into account other mutators.
function Class<Weapon> MyDefaultWeapon() | Called by MutatedDefaultWeapon() to get what the default weapon for this mutator is.
function AddMutator(Mutator M) | Adds the mutator M to the game's mutator list. Normally, this call is not necessary for a generic mutator.
function bool ReplaceWith(Actor Other, string aClassName) | Replaces the Actor class object Other with another Actor class object whose name is aClassName. This is not called automatically by the mutator.
function bool AlwaysKeep(Actor Other) | Called by UT when an actor is going to be destroyed. By returning true, Other won't be destroyed. Default is false.
function bool IsRelevant(Actor Other, out byte bSuperRelevant) | Checks to see if mutators will allow this object to be changed. I'm not certain what purpose bSuperRelevant has yet.
function bool CheckReplacement(Actor Other, out byte bSuperRelevant) | Called by IsRelevant to determine whether or not the Actor class object Other should be replaced. I'm not certain what purpose bSuperRelevant has yet.
function Mutate(string MutateString, PlayerPawn Sender) | Called when players enter commands. Allows mutator to add commands.
function MutatorTakeDamage(out int ActualDamage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation, out Vector Momentum, name DamageType) | Called whenever a player takes damage. Note - this function is called before any damage processing is done to allow mutators to change (or play with) the damage dealt or hit location.
simulated function RegisterHUDMutator() | This registers the mutator as a HUD mutator so that it will receive the PostRender call.

Notice that there are only 5 variable and 14 function members to this class. However, since it extends the Info class (which extends the Actor class), we have access (through class inheritance) to many many MANY more variables and functions. The most important of which would probably be PostBeginPlay(). Let's start with a simple mutator of mine for an example.

// Spectre
// A modification of GhostBoy example provided online

class Spectre extends Mutator;

var bool Initialized;

function PostBeginPlay()
{
if (Initialized) return;

Initialized = True;

Level.Game.RegisterDamageMutator(Self);
}

function ScoreKill(Pawn Killer, Pawn Other)
{
// we have a winner, bump up his glowing and reset the victims'
if ((Killer != Other) && (Other != None) && (Killer != None))
{
Killer.ScaleGlow += 0.2;
Other.ScaleGlow = 1.5;
}

// we have a kevorkian, give him his dues
if ((Other != None) && ((Killer == None) || (Killer == Other))) Other.ScaleGlow = 1.5;

// set visibility so bots react appropriately
Other.Visibility = Other.Default.Visibility * Other.ScaleGlow;
Killer.Visibility = Killer.Default.Visibility * Killer.ScaleGlow;

// call our parent class counter-part function
Super.ScoreKill(Killer, Other);
}

function bool CheckReplacement( actor Other, out byte bSuperRelevant)
{
// Players, bots and carcasses (including gibs) need to be translucent.
if ( Other.IsA('Pawn') || Other.IsA('Carcass')) Other.Style = STY_Translucent;

// Invisibility pickups mess with our Visibility settings.
// We'll just get rid of them completely...
if (Other.IsA('Invisibility')) return false;

return true;
}

function MutatorTakeDamage(out int ActualDamage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation, out Vector Momentum, name DamageType)
{
local float dglow;

// reduce victim's glowing
dglow = float(ActualDamage) / 70.0;
if (dglow <= 0.1) dglow = 0.1;
Victim.ScaleGlow -= dglow;
if (Victim.ScaleGlow <= 0.1) Victim.ScaleGlow = 0.1;

// raise glow of attacker
if (InstigatedBy != Victim) InstigatedBy.ScaleGlow += dglow;

// set visibility so bots react appropriately
Victim.Visibility = Victim.Default.Visibility * Victim.ScaleGlow;
InstigatedBy.Visibility = InstigatedBy.Default.Visibility * InstigatedBy.ScaleGlow;
Super.MutatorTakeDamage(ActualDamage, Victim, InstigatedBy, HitLocation, Momentum, DamageType);
}

The Breakdown :

Let's start from the top and work our way down. First is our class declarator. Specifically, we are subclassing (extending) the Mutator class. Then there are the variable declarations. All variables declared outside the functions are global and static to the object from the point of it's creation.
Next is the function PostBeginPlay(). PostBeginPlay() is called right after the game is fully ready to begin (all objects init'd / created / managed) and the game will start right after we return from this (well, as soon as all classes return from this). However, with the mutator class, PostBeginPlay() is called twice. In order to avoid doing our initialization code more than once, we use a global bool to flag our init'd state or not. The only initialization we handle is registering our mutator as a damage mutator, so that the level will call our MutatorTakeDamage() function. As a good practice (albeit necessary one), initialize all your global vars in PostBeginPlay(). Even though objects are initialized by the engine automatically, never assume your vars have a particular value (this is a good lesson to learn - do paranoia checks on variables just as a matter of safegaurding against potential bugs).
Next is the function ScoreKill(). Every mutator type has this function called. This is the best place to do anything you want to two specific player pawns - the killer and the victim. Players do not have their objects deleted when they die, only reset. However, only certain properties (variables) are reset when a player respawns (by the engine). This is where you want to reset/modify/tweak whatever variables in the player's pawns that you're playing with.
Now we have CheckReplacement(). This function is called for every actor in the level. If there is a particular actor class object that you do not want in the level no matter what, this is the convenient place to do it. By returning false, you are telling UT to get rid of the actor.
Finally, we have the beef of the mutator, MutatorTakeDamage(). Since we registered the mutator as a damage mutator up in PostBeginPlay(), every time a pawn *is about to take damage* this function is called. This allows you to change the damage dealt to the pawn, where it was hit, or process other things based on the information passed to the function, such as changing the translucency of the pawn based on how much damage was taken.


The Mutator Class

Navigation Point Network

by Pfoenix

Pfhoenix

mod exemplar

NavigationPoint Networks refers to the method of path finding that Unreal / Unreal Tournament bots utilize. Though a class attempting to cover all aspects of navigation AI would far exceed the bounds of a simple tutorial, I will explain the basics of the NavigationPoint Network, as well as what Unreal / UT does with the bots.

Knowing the Path

The NavigationPoint Network uses a 'network' of 'nodes' (usually pathnodes) to find its' way around a level. The names are a resultant of the similarities in nature of the method - like a telephone or computer network, each node is a connection point, and connections between nodes are the available paths of travel on the network.

Using the Path

In order to use the network, there are several requirements : a Pawn subclass with proper variables set and a map with a network properly built. Let's break it down a bit further.

Pawn subclass. A Pawn subclass would be a Bot, Player (via PlayerPawn), or a ScriptedPawn (there are more, these are just examples). Pawns access the network via two native functions - FindPathTo() and FindPathToward(), the difference being FindPathTo() tries to find a path to a particular location while FindPathToward() tries to find a path to a particular Actor. The functions are declared as such :

native(518) final function Actor FindPathTo(vector aPoint, optional bool bSinglePath, optional bool bClearPaths);

- aPoint is the location in world coordinates you want to find a path to
- bSinglePath will tell the function to try to find a no hop (straight shot) path
- bClearPaths will tell the function to wipe clear the RouteCache array, where the paths are stored. If this is False or omitted, the found path will be added to the end of whatever path is in RouteCache already.
native(517) final function Actor FindPathToward(actor anActor, optional bool bSinglePath, optional bool bClearPaths);

- anActor is the Actor the function will try to find a path to
- bSinglePath will tell the function to try to find a no hop (straight shot) path
- bClearPaths will tell the function to wipe clear the RouteCache array, where the paths are stored. If this is False or omitted, the found path will be added to the end of whatever path is in RouteCache already.

In order for these two functions to do you any good, the Pawn subclass must first have it's collision set to (bCollideWorld, bCollideActors, bBlockActors, and bBlockPlayers), the DefaultProperty values of those four bools need to also be set to True, the CollisionHeight and CollisionRadius must be non-zero, and the Pawn subclass must be standing on the ground. If these conditions are met, a call to FindPathTo/ward will result in the array RouteCache to be modified/filled according to whether or not a route was found and if bClearPaths was True, False, or omitted. Keep in mind that simply calling FindPathTo/ward() will not result in movement. Custom AI will have to handle the actual movement based upon the RouteCache array, while Bots and other Pawn subclasses are complex, with states doing many different things. This tutorial couldn't hope to cover the Bot AI without turning into a dissertation.

In-map network. The network layed out in the map has to follow some basic, but simple rules :
- all pathnodes must be close to the ground (within 32 Unreal units). This is not only key and vital, but the cause of more problems when dealing with the pathing network than anything else - literally, despite whatever size CollisionHeight is set to in the Pawn subclass, the pathnodes MUST be within 32 Unreal units of the level geometry below them
- pathnodes must be within 1000 Unreal units in order for a path to be built
- a path is built between any pathnode within LOS (Line Of Sight) of each other.

Paths, when displayed in Ued (right click on a view window's menu area, select View->paths), will be one of two colors :
Blue : the path between the two pathnodes is considered a good path, free of obstruction with enough width clearance
Red : the path between the two pathnodes is considered a poor path, though it may have LOS, there may be level geometry that would interfere with a pawn moving on the straight line between the two pathnodes

What that means blue paths will be taken over red ones, unless there is no other option other than to take a red path. You can prevent red evaluated paths be ensuring enough clearance around the pathnodes as well as the area between them.

Walking the Path

Now you should have all the basic information necessary to understanding how to create and use the NavigationPoint Networks utilized by the Unreal engine. Sadly, there are few to no references written by Epic programmer Steve Polge (originator of the AI used in Unreal / UT) which adequately cover the basics from a programmer's standpoint. Hopefully, you will have found this quick tutorial useful enough to get started on learning the intricate details of the Unreal / UT AI.


Penetrating Weapons

by mr. self-destruct

mr.self-destruct

Theory

In Unreal Tournament weapons that immediately hit their target use a trace to locate the target. The trace begins at the player who fired the weapon, travels along their line of sight until it intersects an object (be it wall or player). If we simplify the problem by treating it in 2D, the diagram below illustrates what happens when a normal weapon shoot at a wall:

You'll have to excuse the dodgy diagrams in this tutorial, my drawing skills are somewhat lacking :P

Now to make a weapon appear to fire through a wall we need to begin a second trace starting at a distance x from the where the first trace ended. x is the penetration factor, how thick a wall the weapon will appear to shoot through. When the wall is thinner than x the 2nd trace will continue along until it intersects another object:

When the wall is thicker than x the 2nd trace will hit the inside of the wall and stop:

In the real world it's slightly more complicated that than. A player is soft, so a powerful gun will shoot through them easily, a wall is hard and so the weapon will penetrate through it less. The problem lies in the fact that player's are quite thick, so the penetration factor must be quite high to go through them, with the result that it'll go through thicker walls than we want it to. The solution to the problem is to have two penetration factors, one for pawns and one for anything else. We then check what the first trace hit and then use the relevant penetration factor.

Code

"Great you've explained it all and yes the method is quite simple, but how to implement it?" I hear you say. Easy! All you need to do is override the TraceFire() function to implement the second trace. Before I give you the code, remember that it doesn't cut and paste into a new weapon too well. In part this is because it calls ProcessTraceHit() twice, and this is where things such as shell cases get spawned.

// Weapon fire that goes through wall

// Penetration through walls
var() float Thick;
// Penetration through pawns
var() float PawnThick;
function TraceFire( float Accuracy )
{
local vector HitLocation, HitNormal, StartTrace, EndTrace, X,Y,Z;
local actor Other;
local Pawn PawnOwner;
local float Penetration;

PawnOwner = Pawn(Owner);

Owner.MakeNoise(PawnOwner.SoundDampening);
GetAxes(PawnOwner.ViewRotation,X,Y,Z);
// First trace, just like ordinary weapon
StartTrace = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
AdjustedAim = PawnOwner.AdjustAim(1000000, StartTrace, 2*AimError, False, False);
EndTrace = StartTrace + Accuracy * (FRand() - 0.5 )* Y * 1000 + Accuracy * (FRand() - 0.5 ) * Z * 1000;
X = vector(AdjustedAim);
EndTrace += (10000 * X);
Other = PawnOwner.TraceShot(HitLocation, HitNormal, EndTrace, StartTrace);
// Deal with first target
ProcessTraceHit(Other, HitLocation, HitNormal, X,Y,Z);

// Second trace, start location takes into account previous target
if (Other.IsA('Pawn'))
Penetration = PawnThick;
else
Penetration = Thick;
StartTrace = HitLocation + HitNormal + (Penetration * X);
EndTrace = StartTrace + Accuracy * (FRand() - 0.5 )* Y * 1000 + Accuracy * (FRand() - 0.5 ) * Z * 1000;
EndTrace += (10000 * X);
Other = PawnOwner.TraceShot(HitLocation, HitNormal, EndTrace, StartTrace);
// Deal with second target
ProcessTraceHit(Other, HitLocation, HitNormal, X,Y,Z);
}

defaultproperties
{
// Walls are hard, so gun penetrates less
Thick=20.0
// Pawns on the other hand are soft and tend to be thicker than
// walls you want to penetrate
// 17 is UT's default player collision radius, so make the gun
// just penetrate a pawn
PawnThick=36.0
}

What?! Only nine extra lines strapped on the end of the standard TraceFire() function, I said it was easy to implement ;)

Taking it Further

Having outlined the basic principles behind this, it's possible to take it further and devise a technique that will cope with shooting through multiple targets.
The principle behind this is much the same, but it requires several loops and a counter to keep track of how many times we've traced ahead. I'm not going to go into an in-depth discussion of how the technique works, instead I'll just present you with the code (which is quite well commented):

// Maximum number of times to trace ahead
var int MaxPenetration;
// How far to trace ahead
var float PenetrationDepth;
// First shot?
var bool bFirst;

// What did we just hit?
function int ReportMaterial(actor Other)
{
if (Other != None)
{
if (Other == Level)
return 1; // Level
else if (Other.bIsPawn)
return 2; // Pawn
else if (Other.IsA('Decoration'))
return 3; // Decoration
}
else
return 4; // Air
}

// Multiple penetration TraceFire()
function TraceFire (float Accuracy)
{
local vector HitLocation, HitNormal, StartTrace, EndTrace, X,Y,Z, EntryLocation;
local actor Other, LastHit, BOther;
local pawn PawnOwner;
local int Penetration;
local bool bAfterFull;

// Prepare variables
PawnOwner = Pawn(Owner);
Penetration = MaxPenetration;
Owner.MakeNoise(PawnOwner.SoundDampening);
GetAxes(PawnOwner.ViewRotation,X,Y,Z);
StartTrace = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
AdjustedAim = PawnOwner.AdjustAim(1000000, StartTrace, 2*AimError, False, False);
EndTrace = StartTrace + Accuracy * (FRand() - 0.5 )* Y * 1000 + Accuracy * (FRand() - 0.5 ) * Z * 1000;
X = vector(AdjustedAim);
EndTrace += (10000 * X);
bFirst = True;
while (Penetration > 0)
{
// Initial trace
if (bFirst)
{
Other = PawnOwner.TraceShot(HitLocation, HitNormal, EndTrace, StartTrace);
bFirst = False;
bAfterFull = True;
Penetration--;
EntryLocation = HitLocation + HitNormal;
ProcessTraceHit(Other, HitLocation, HitNormal, X,Y,Z);
}
// Full length trace
else
{
StartTrace = EndTrace;
// NB: For more realism, randomly adjust the aim after shooting through something
EndTrace += (10000 * X);
Other = PawnOwner.TraceShot(HitLocation, HitNormal, EndTrace, StartTrace);
Penetration--;
bAfterFull = True;
EntryLocation = HitLocation + HitNormal;
if ((LastHit == Level && bAfterFull) || Other != LastHit)
ProcessTraceHit(Other, HitLocation, HitNormal, X,Y,Z);
}
// Trace ahead through whatever we've hit
while (Penetration > 0 && Other != None)
{
LastHit = Other;
// After a full length trace we trace from where we hit
if (bAfterFull)
StartTrace = HitLocation + HitNormal;
else
StartTrace = EndTrace;
EndTrace = StartTrace + (PenetrationDepth * X);
Other = PawnOwner.TraceShot(HitLocation, HitNormal, EndTrace, StartTrace);
Penetration--;
if (LastHit != Other)
break;
bAfterFull = False;
}
// Back trace for exit decal
BOther = PawnOwner.TraceShot(HitLocation, HitNormal, EntryLocation, EndTrace);
if (BOther == Level)
{
Spawn(class'UT_WallHit',,, HitLocation + HitNormal, Rotator(HitNormal));
}
else if ((BOther != self) && (BOther != Owner) && (BOther != None))
{
if (!BOther.bIsPawn && !BOther.IsA('Carcass'))
spawn(class'UT_SpriteSmokePuff',,, HitLocation + HitNormal * 9);
else
BOther.PlaySound(Sound'ChunkHit',, 4.0,, 100);
}
// NB: VSize((HitLocation + HitNormal) - EntryLocation) = thickness of what we just
shot through }
}

defaultproperties
{
MaxPenetration=4
PenetrationDepth=10.0
}

The above code even generates entry & exit decals :)

Do note however that a trace is a quite expensive operation to perform and too many going on at once can slow things down. The combination of a small PenetrationDepth & high MaxPenetration and/or using this technique with a weapon with a very high rate of fire could produce a notable drop in performance (but most likely only in the case of a multi-player game with many players using that weapon at once).


Portal Hud

by Luke Wenke

class PortalsHUD extends UnrealHUD;

// This is a subclass of UnrealHUD which adds portals to your view,
// you could also subclass UT's ChallengeHUD to add the portals in UT.

function PostRender(canvas Canvas)
{
// A function called DrawPortal will be used four times to create
// four extra views.  DrawPortal is a function of the Canvas. Here
// is the function definition:
// Canvas.DrawPortal(int X, int Y, int Width, int Height, actor CamActor,
//                   vector CamLocation, rotator CamRotation,
//                   optional int FOV, optional bool ClearZ);
//
// Note: (this is for Unreal 224- the problems may be fixed in later verisons)
//
// - Sprites are reflected from the right side of the screen to the left, and
// from the bottom of the screen to the top, so it is best to use DrawPortal
// at the top-left corner, or taking up the whole top or whole left of the
// screen.
//
// - The player's mesh won't display unless the player's bBehindView is True
// (you can type "behindview 1" and "behindview 0" in the console to turn
// the behindview on and off)
//
// - The sound is only calculated for the player's main camera and not for the
// extra views.
//
// - The CamActor parameter currently doesn't do anything, but you need to put
// in a valid actor there so that the script compiles.
//
// - ClearZ specifies whether the Z-buffer should be cleared or not- this doesn't
// seem to make any difference.
//
// - The portals do not resize and reposition themselves when you adjust
// the screen-size using + and -.
//
// - Parts of the portals which are not part of the world are not visible
// (instead of being black) to see this in action, move into walls
// while watching the "facing player cam" portal.

  local Projectile projectile1, proj;
  local Pawn pawn1, p;
  local rotator CirclingRotation;

  projectile1 = None;

  // Pick the last found projectile (the newest one)
  foreach AllActors(class'projectile', proj)
    projectile1 = proj;

  pawn1 = None;
  foreach AllActors(class'Pawn', p)
    // If the pawn is not the player and is not a HorseFly
    // (portals using individual FlockPawns such as HorseFlies crash
    // Unreal for some reason).
    if (p != owner && !p.IsA('FlockPawn'))
      // pick the last found pawn (the newest one)
      pawn1 = p;

  // Setup the font
  Canvas.Reset();
  Canvas.Font = Canvas.MedFont;
  Canvas.DrawColor.r = 255;
  Canvas.DrawColor.g = 255;
  Canvas.DrawColor.b = 255;

  // Projectile cam
  if (projectile1 != None)
  {
    // Portal's starting X
    // (the number of pixels from the left side of the screen)
    Canvas.DrawPortal(0,

    // Portal's starting Y
    // (the number of pixels from the top of the screen)
    0,

    // height of the portal (30% of the total screen width)
    Canvas.SizeX*0.3,

    // width of the portal (30% of the total screen height)
    Canvas.SizeY*0.3,

    // the camera actor
    // it doesn't seem to make any difference what you put here,
    // as long as it is a valid actor
    self,

    // the location of the camera (40 units behind the projectile)
    projectile1.Location -40 * vector(projectile1.Rotation),

    // the rotation of the camera
    projectile1.Rotation,

    // the field of view angle of the camera (optional)
    90);

    // Display the title for the portal
    Canvas.SetPos(Canvas.SizeX*0.02, Canvas.SizeY*0.05);
    Canvas.DrawText("Projectile Cam");

    // Display the name of the projectile
    Canvas.SetPos(Canvas.SizeX*0.02, Canvas.SizeY*0.25);
    Canvas.DrawText(projectile1.name);
  }

  // pawn cam
  if (pawn1 != None)
  {
    Canvas.DrawPortal(Canvas.SizeX*0.7,
    0,
    Canvas.SizeX*0.3,
    Canvas.SizeY*0.3,
    self,
    pawn1.Location,
    pawn1.Rotation);

    // Display the title for the portal
    Canvas.SetPos(Canvas.SizeX*0.72, Canvas.SizeY*0.05);
    Canvas.DrawText("Pawn Cam");

    // Display the name of the projectile
    Canvas.SetPos(Canvas.SizeX*0.72, Canvas.SizeY*0.25);
    Canvas.DrawText(pawn1.name);
  }

  // facing player cam
  // these two portals turn on if behindview is on
  if (PlayerPawn(owner).bBehindView)
  {
     Canvas.DrawPortal(0,
     Canvas.SizeY*0.7,
     Canvas.SizeX*0.3,
     Canvas.SizeY*0.3,
     self,

     // Start at the player's location and move 100 units
     // in the direction in which they are facing.
     owner.Location + 100*vector(owner.Rotation),

    // Make the camera have the opposite rotation to the player
    // by converting the rotation to a vector, inverting the vector,
    // and converting the vector to a rotation.
    rotator(-vector(owner.Rotation)));

    // Display the title for the portal
    Canvas.SetPos(Canvas.SizeX*0.02, Canvas.SizeY*0.75);
    Canvas.DrawText("Facing Player Cam");

    // Circling player camera
    // Begin with the player's rotation,
    CirclingRotation = owner.Rotation;

    // look down,
    CirclingRotation.Pitch -= 8000;

    // and rotate every 10 seconds.
    CirclingRotation.Yaw = (Level.TimeSeconds*65536) / 10;

    Canvas.DrawPortal(Canvas.SizeX*0.7,
    Canvas.SizeY*0.7,
    Canvas.SizeX*0.3,
    Canvas.SizeY*0.3,
    self,

    // Start at the player's location and go backwards 60 units
    // in the direction of the circling rotation.
    owner.Location - 60*vector(CirclingRotation),

    // Give the camera the circling rotation
    CirclingRotation);

    // display the title for the portal
    Canvas.SetPos(Canvas.SizeX*0.72, Canvas.SizeY*0.75);
    Canvas.DrawText("Circling Player Cam");
  }

  // Draw the menu and UnrealHUD on top by calling the PostRender
  // function in our parent class.
  Super.PostRender(Canvas);
}

class PortalsGameInfo extends UnrealGameInfo;

// In order to have players use the new HUD with portals just make
// a new gametype, and set the HUDType variable to the new HUD class.

defaultproperties
{
HUDType=PortalsHUD
}


Rain

by c0mpi1e

//=================================================
// RainGen.
// author: c0mpi1e(Carlos Cuello)
// Total Time So Far: 20 hrs.
//
// legal: Everything in this class is 100% original and is the
// property of me. It was originally
// produced for the USCM:Infestation TC, and any revisions
// to this mod will be used in that. This is the final
// version that I will release to the public. You may use
// this in any map and release it as part of any map you
// create as long as you give me full credit. If you need
// anything added in particular you can email me and I'll see
// what I can do.
//
// This is basically what controls the Rain and is the only thing you
// will have to work with. I wanted to keep this something that anyone
// can use, tried to keep it very configurable and tried to make
// everything be handled from UnrealEd. So for all you map makers,
// simply add as many raingen's to the ceiling of the sky where you want
// it to fall from. The RainGen delivers a limited range of raindrops, so
// do not expect one raingen to create a monsoon. To change the various
// settings for the rain, select all the RainGens in your map and click
// on the properties dialog box, then click on the several Rain propety
// menu's that appear(Rain_Behaviour, Rain_Looks, Rain_Sounds). The
// intensity variable should be kept between 0 and 5 or so to keep
// rendering speed good. DropSpeed should be negative for faster rain,
// and positive for slower rain, however beware that a positive integer
// greater than 100 or so will cause the raindrops to go up and hit the
// ceiling.
//
// Note: For this release, lightning is not working, if you absolutley
// need it, then email me and I'll see what I can do.
//=================================================
class RainGen expands Effects;

// Variables you can manipulate from UnrealED
// This enum lets a mapper or whatnot choose between 3 different sprites
// for the rain drop. The parenthesis after var tells unreal that this
// variable can be changed from Unrealed, if you put something in the
// parenthesis then that will be the parent menu of the variable.
var(Rain_Looks) enum ERainType
{
Rain_Drop,
Rain_Line,
Rain_LongLine
} RainDrawType;

var(Rain_Looks) float DropSize; // The size of each drop
var(Rain_Behaviour) int intensity; // The intensity of the rain
var(Rain_Behaviour) int DropSpeed; // determines the drop speed. Neg numbers
// make it drop faster, positive slows it
// down, should be modified for the
// default properties dialog

var(Rain_Behaviour) int RainRadius; // The radius of the rain, which is
 // random from 0 to RainRadius
var(Rain_Behaviour) bool bThunder;
var(Rain_Behaviour) bool bLightning; // not implemented yet
var(Rain_Sounds) Sound ThunderSound1;
var(Rain_Sounds) Sound ThunderSound2;
var(Rain_Sounds) int SoundRadius;
var(Rain_Sounds) int RainVolume;

// Private Variables we want to keep to ourselves
var int ct; // misc counter variable, used for
// for loops, rather have it as a global
// variable because we might use it more
// than once.
var Effects D; // the actual raindrop
var Effects L; // used for lightining
var vector NewLoc; // the location of the random rain drop

// Set all our variables.
simulated function PreBeginPlay()
{
Super.PreBeginPlay();

// We want to enable the timer
Enable('Timer');

// Set the timer for every ten clicks we want the thunder to be
// handled here, randomly. If you put this into the tick function
// it slows things down considerably.
SetTimer(10, true);

// Play the rain sound, using the Ambient slot
PlaySound(EffectSound1, Slot_Ambient, RainVolume,, SoundRadius);
}

// Find a random number from -Max to Max
function int RandomNeg(int Max)
{
local int k;
k = Rand(Max + 1);
if (Rand(2) == 1)
k = -k;
return k;

}

// This is where thunder and lightning are handled
function Timer()
{
Super.Timer();
if (bThunder == true && Rand(5) < 3)
{
// Randomly choose which thunder sound to use
 if (Frand() < 0.5)
PlaySound(ThunderSound1, Slot_Misc, 25, true);
else
PlaySound(ThunderSound2, Slot_Misc, 25, true);
}

// If we go into the timer, but have bThunder set to false
// then we no longer want to call the timer, we can put this before
// in PreBeginPlay, but because we use default properties
// to handle everything, we will not know then.
 if (bThunder == false)
Disable('Timer');
}

// This is where everything takes place
function Tick(float deltatime)
{
// For the number of intensity that is set from UnrealEd, then
// spawn a new raindrop
for (ct = 0; ct < intensity; ct ++)
// Find a new location for the spawned RainDrop, using my
// function RandomNeg() and base it off of the current Location
// we only want to produce one on the horizontal plane of
// sky or ceiling, so we leave the Z axes alone.
NewLoc.X = Location.X + RandomNeg(RainRadius);
NewLoc.Y = Location.Y + RandomNeg(RainRadius);
NewLoc.Z = Location.Z;

// Spawn a raindrop at NewLoc
 d = Spawn(class'RainDrops',,,NewLoc);

// Set the size to what the user specified
 d.DrawScale = DropSize;

// Same with the speeed
 d.Velocity.Z = DropSpeed;

// Depending on what you choose for RainDrawType then set
// the appropriate Texture.
 switch RainDrawType
{
case Rain_Drop:
d.Texture = Texture'RainDrop4';
break;
case Rain_Line:
d.Texture = Texture'RainLong';
break;
case Rain_LongLine:
d.Texture = Texture'RainLonger';
break;
default:
d.Texture = Texture'RainDrop4';

}
}
}

//============================================
// RainDrops
//============================================
class RainDrops expands Effects;
var effects d;

function PreBeginPlay()
{
Super.PostBeginPlay();

// Make the rain actually fall :)
 SetPhysics(PHYS_Falling);
}

// When a drop hits a wall or lands on the ground then create
// a small rain puddle effect
function HitWall( vector HitNormal, actor HitWall )
{
Super.HitWall(HitNormal, HitWall);

// 60% chance that there will be a puddle left on the ground
// do this to keep performance up
 if (Frand() < 0.8)
Spawn(class'RainPuddle',,,Location);
Destroy();
}

// Same for Landed
function Landed(vector HitNormal)
{
Super.Landed(HitNormal);
if (Frand() < 0.8)
Spawn(class'RainPuddle',,,Location);
Destroy();
}

//===========================================
// RainPuddle.
// Most of the code here is copied from the RingExplosion
// code, basically I just changed the DrawScale to a smaller
// value, I do not take any credit for this outside of that,
// its makes a very nice effect.
//===========================================
class RainPuddle expands Effects;

var bool bSpawnOnce;

simulated function Timer()
{
local WaterRing r;

if ( Level.NetMode != NM_DedicatedServer )
{
r = Spawn(class'WaterRing',,,,rot(16384,0,0));
r.DrawScale = 0.02;
r.RemoteRole = ROLE_None;
}
else
Destroy();
if (bSpawnOnce) Destroy();
bSpawnOnce=True;
}

simulated function PostBeginPlay()
{
SetTimer(0.3,True);
}


Replication De-Obfuscation

Introduction

Ask any halfway decent UnrealScript programmer what the most confusing aspect of Unreal coding, and he'll be sure to tell you replication. (or perhaps PlayerMovement or pawn/bot AI :) I've been there myself, and I still have trouble with it sometimes, but I think I know enough to write some documentation. Lots of trial and error helped me get far, along with various insights from people that had the source code to the engine. I've tried to piece it all together to create this document. I have however, recently gotten a lot more information about exactly how replication works, which has helped me immensely in understanding replication. Since I can't post that information directly because of NDA, I'll try my best to explain it to you through this networking documentation. Hopefully I'll be able to expand upon what was described in Epic's documents at: http://unreal.epicgames.com/Network.htm and http://unreal.epicgames.com/UTMods.html. Please read it first, as it will help a lot with background and context. In writing this document, I'm going to assume you've programmed in UnrealScript before, you have at the very least considered the problems of replication, you are reasonably intelligent, you know how to read, and you think my jokes are funny.

First, Unreal Tournament uses a client-server architecture. The client is basically a dumb terminal, that sends data to the server about where the player moved, if they're jumping, if they're shooting, etc. It displays to the user what is given to it by the server. The client's information is necessarily out of date with what exists on the server, because of lag, ping time, and other factors. So in order to present a believable world, the client has logic to simulate what it thinks the server will be sending it. It knows the laws of physics, and that if something is travelling in a straight line, then it will contine to travel with that same velocity. Likewise, if it's falling through the air, it's likely to continue to be accelerated under the force of gravity. The dumb terminal predicts where how the game state will be progressing, and so can provide the user with a more believable game. On the other end of the connection is the server, which holds the authoritative state of what's going on in the game. If the server thinks you are dead, then you are dead. Like your teachers, they're never wrong, no matter how much evidence you've seen to the contrary (like how you *thought* you dodged that rocket). The client gets information sent to it by the server (like where other people are, what things have been shot, etc) , and sends other information back to the server (like where the client wants to move, shoot, etc). In the client-server architecture, the client only communicates with the server, and the server communicates with all of the clients (people connected to the server).

Server as Authority

With the recent brew-ha-ha regarding the ZeroPing mod, which aims to give the client more control, there have been two sides to the issue of why the server as authority is the best model.

A good description of the history of the networking architectures in games can be found at the top of the tech page's networking document. Go read the "History" section now, and then come back. The current model is that of a client-server architecture, where the client has prediction to minimize the effects of lag. In current versions of UT, the client tells the server all about it's input. Where is the user looking, in which direction are they moving, and are they firing primary or secondary fires.. The server then uses that data to calculate information about the player, and to tell other clients about that player. For the most part, that is all there is to it. ZeroPing pioneered an idea of giving the client more power. It allowed the client to decide whether they hit the other player. In theory, this sounds great. The user gets to decide what's happening, and if they hit the player, then they hit the player. Unfortunately, there are problems with this idea.

In a large-scale game like UT or Q3A, many people try to cheat. The people that make the game have to prevent that from happening. With these games, the client does so little logic, that there is little room to cheat. The client sends its data to the server, and the trusted server decides whether they hit the player or not. Cheats are extremely limited in what they can do, as they can only modify the direction the player is going, and whether to cheat or not. It's not something that is really worthwhile. However, when you have something like ZeroPing, you are letting the client decide whether or not you hit the player. A cheat can pretend that it hit every player, and can wreck havoc in such a game, where it is killing everyone the moment they enter view, and sometimes even getting repeated kills ten times in a row on a single player as they respawn and then are 'hit' again. Mods like ZeroPing are mods, and so do not ahve the same public appeal that a full game does. As such, mods are less likely to be hacked for cheats. But it does not make them immune. If game makers were to use the approach that ZeroPing uses, there would be a flood of cheats within weeks of the game's release. You can understand the resistance that the game companies have for such an approach. It is not because it's the 'not-invented-here' syndrome as many have suggested, but rather that it really is much more open to cheating.

As a side note, I guess the ZeroPing author does realize this. He has hidden his code to make it impossible to cheat with. He took the security through obfuscation approach. This will work for awhile, until code decompilers become available, or the code gets out. While I am not working on any of these myself, I do know of some UnrealScript code decompilers in the works. So this approach really will not work in the long run.

Replication Overview

Replication deals with how information is sent from the server to the client and vice versa. Because of bandwidth limitations for modems, not everything can be sent, and because of the unpredictability of the Internet, not everything can be ensured of arriving on time. Only a subset of all the information is sent to the client, and replication deals with that subset that travels from the server to the client, and deals with how the client sends its relevant information back to the server.

While the definition of replication may sound simple, there is a lot of underlying assumptions and quirks that you must be aware of, which UT uses in the interest of optimum bandwidth and speed. It's an unmapped jungle out there, and many an explorer has been lost to the dangerous native inhabitants. This guide you are reading is your map and survival guide.

First, the Unreal server does some logic like the following for each client connected:

  1. Run all events (like tick, timer, hitwall, etc)
  2. Go through each client connected to the server
  3. Get the list of relevant actors for this client.
  4. For each actor, replicate variables that need to be replicated.
  5. Replicate any function calls that should be replicated to that particular client, if they were called during the previous server-side events run above.

The client does the following logic:

  1. Receive data from the server, and update its local copies of the actors
  2. Run any replicated calls that were called on the server
  3. Run any simulated events (like tick, timer, hitwall, etc), and do the local playerpawn handling
  4. Find out what replicated were called on the client and need to be replicated to the server, and send them

If that didn't make any sense, don't worry about it. They just outline the main parts of replication, and they will all be explained later.

If you did understand that, there's still plenty to learn. UT has a lot of logic going on under the hood in regards to replication, most of which is not immediately apparent. That was the purpose of this document, to explain these mysteries to you, the reader, so that your networking development will go that much more smoothly. Again, all this will be explained in due time, assuming you read the whole document. :)

Relevant Actors

First, we need to define what a relevant actor is. A client, as the dumb terminal, needs to know about everything that it will need to display on screen. It needs to know about the other players, and weapons in the level, if any projectiles are visible, if the flag is visible, health packs, etc. All of these actors constitute the relevant set of actors. how is the relevant set of actors determined? If an actor is not relevant, no amount of replication statements or voodoo magic will cause its information to be sent to the client. It must be relevant to that particular client in order for data to be sent to that client. For Unreal / Unreal Tournament, the method of determining relevant actors is as follows (ripped from the tech page's networking document):

The following logic is performed on each actor, and you should be able to tell whether it is relevant. The actor must pass two discrete sets of steps in order to be considered relevant. One it passes the first test, it must then pass the second. The rules higher in the list have precedence over rules that follow them:

  1. If it is bNetTemporary, then it does not pass the first stage.
  2. If it is not bStatic and not bNoDelete, then it passes the first stage.
  3. If it is a LevelInfo, it passes the first stage.
  4. If it is a temporary network actor, (as defined by bNetTemporary), and it's been sent to this client already, then it does not pass the first stage. These types of actors will be decribed in more detail later.
  5. If its Role is ROLE_None, then does not pass the first stage.
  6. If it is bAlwaysRelevant, and time since the last relevancy is less than 1 / NetUpdateFrequency (described farther below) seconds, then it does not pass the first stage. This basically means an actor will only update it's variables to the client NetUpdateFrequency times per second. (NetUpdateFrequency values: Actor: 100, ZoneInfo: 4, GameReplicationInfo: 4, PlayerReplicationInfo: 2, or Inventory: 8).
  7. If it is bNetOptional, and it has a non-zero LifeSpan (meaning it does not exist forever), and it is not in the first 150 ms of its lifetime, then it passes the first stage. Any attempt at replicating a bNetOptional actor after the first 150 ms, (because it was pushed off the replication list due to bandwidth contraints for that client, etc,) will fail.
  8. If the time since the last relevancy is greater than 1 / ~NetUpdateFrequency seconds, it passes the first stage. (This is a more finely tuned optimization of NetUpdateFrequency, tuned to the type of actor. It will only perform the calculations needed if it has passed through the weeding techniques above.)
  9. It does not pass the first stage.

If it passed all of those steps, it's not through and clear to be relevant yet. It has another step to go through. If it is deemed relevant during the following steps, then it is relevant to this client.

  1. If it is bAlwaysRelevant, then it is relevant.
  2. If it is owned by the client or owned by the actor we are viewing through (as returned by PlayerCalcView), then it is relevant.
  3. If it is the client or the actor we are viewing through (as returned by PlayerCalcView), then it is relevant.
  4. If its Instigator is the client, then it is relevant.
  5. If it has an ambient sound and is within 'audible distance', then it is relevant.
  6. If it is a weapon that is owned by a visible Pawn owner, then it is relevant.
  7. If it is bHidden or and not bBlockPlayers and the AmbientSound is none, then the actor is not relevant.
  8. If it is not relevant (per the above tests), but if any of the above conditions made it relevant within the last RelevantTimeout seconds, (by default, five seconds, but is defined in UnrealTournament.ini:[IpDrv.TcpNetDriver],) then it is relevant.
  9. It is not relevant.

Those rules, while seeming complicated, are exactly how UT determines what is relevant to each client. Many times such checks are not related to what you are doing, but they are always good to know. Thinking about it, it makes sense. If something is not visible, then the client probably does not need to know about it. If it's a player on the other side of CTF-LavaGiant, what use does this client have for it? Or if it's an invisible pathnode used for Bot AI, the client also has no use for it. Sending data and variables for such actors would be wasteful on a tiny little 28.8 kbps modem.

Working this discussion into a guideline for your own code, you should set your actors' bAlwaysRelevant to true if they are data storage units that the client needs to know about, like PlayerReplicationInfo or GameReplicationInfo. Things like PlayerReplicationInfo, which store information about the player, are always relevant. This allows a client to view the Scoreboard and see the information (name, score, ping, packetloss, etc) for everyone in the level, regardless of whether that player actor is relevant to the client. PlayerReplicationInfo's allow precious information that's small, bandwidth wise, to be relevant and replicated to each client, yet have information like the location, velocity, weapon, animations, etc of the player to not be replicated when it's not necessary (because it's in the Pawn/PlayerPawn, which is not always relevant.) Hopefully I've not lost you here. It's an important thing to know and remember about Unreal replication. Where to put your variables, and how to make them relevant to the client. If you needed some important game information to be seen by all clients, your best bet would be to subclass ReplicationInfo and utilize that for your data variables. Information that is only needed when it's seen is best put in regular actors, that will go in and out of relevancy as time passes.

In a nutshell, if the client needs to know about it, they will. All inventory is relevant to the client, as is all nearby players. All projectiles and weapon effects that are visible are relelvant. Anything that affects the player's world on the client, will be replicated. This includes things that block the player's movement, or actors that play ambient music. There is an overhead to spawning a new actor in netplay, and so UT does not immediately remove an actor from the relevancy list when it goes out of view. It gives it a few seconds before it is really considered not relevant. Oh, and UT takes into account the fact that a player may be viewing through another actor's eyes, as in the case of the GuidedWarhead, or the teammate views when you hit the number keys on the right side of your keyboard.

NetPriorities

While that's the "simple" description, figuring out why things happen can get a bit more complicated. Unreal Tournament gives different priorities for different types of actors. NetPriority, which should typically be between 1 and 3, determines how to prioritize a given actor's bandwidth "allocation" in the stream being sent to each client. Actors are first sorted by a calculation based upon their priority (adjusted to take into account how close the client is looking at them, etc.) Actors marked bNetOptional are sent to the bottom of the list. So....actors with a higher priority are sent first in the bandwidth stream, and when the connection becomes saturated, any remaining actors are starved of bandwidth until later. (UT remembers which actors have not been replicated, and so it can give bNetOptional actors 150 ms to get replicated before they are discarded. See the above relevancy list for more information.)

Here's a wide and almost complete sampling of UT's NetPriorities:

Bots | 3.0
PlayerPawns | 3.0
GuidedRedeemer | 3.0
Movers | 2.7
Projectiles | 2.5
Carcasses | 2.5
Other Pawns | 2.0 (Spectators, Titans, Bunny Rabbits, etc)
Effects | 2.0 (sparks, blood, smoke)
Simpler effects | 1.4 (shell casings)
Inventory | 1.4 or 2.5
Everything else | 1.0

This shows that the server considers a Player's (be it bot or playerpawn) information to be much more important than something like bullet casings from a gun. And it makes sense. A guided redeemer also has unpredictability to it, since it is controlled by a player, and thus needs a higher NetPriority. A projectile follows the simple Physics given to it, eg: PHYS_Falling, PHYS_Pojectile, and so they are not very unpredictable. Thus, its NetPriority is not as high as a player's. However, projectiles are still quite important to gameplay (doesn't it suck to get hit by that rocket you never saw? :), and they get a high NetPriority. It's the same with the carcasses, since their animations as they fly through the air or fall to the ground are quite important (not to gameplay, but to that touchy-feel-good feeling when you kill someone.) You should use these examples as a guide when creating your own actors that need a different priority.

One additional thing to note is that you can change the NetPriority on the fly. This is done with Inventory, for example. It exists as 1.4 for most of its life, but when it is thrown from a player's inventory, it now is a moving actor with more importance attached to it. It is then given a higher NetPriority. Once it hits the ground, it gets a NetPriority of 1.4 again, since it does not need to be updated as often when it is sitting stationary on the ground.

In general, all of the relevant actors for a particular client are put in an array each tick, and then sorted by their priorities. The server then starts replication the actors, starting with the highest NetPrioritized actor, working it's way down. UT then stops replicating actors when the bandwidth becomes saturated. That's why it's important to prioritize your actors correctly, so that when a lot of actors are on screen, or on the lowly 28.8K connections, UT will know how to perform triage, and who to starve of bandwidth first. If an actor is not replicated, the variables it was supposed to tell the client about are not forgotten. They will be put on the list during the next tick, to have another go at getting replicated. Note that doubling the size of the actor's NetPriority does not actually change anything in regards to giving it more bandwidth, since a NetPriority only has meaning in relation to other NetPriorities. Since 3.0 is the highest on the list, there is no real difference between giving your actor a NetPriority of 4.0 and 4000.0, since they will both be placed at the top of the list.

Roles and RemoteRoles Introduction

Now is a good a time as any to explain the purposes of the various roles in Unreal. Roles simply guide UT in determining what role this particular actor plays in the game of replication. For example, a player needs to be replicated quite differently from an ammo box sitting on the ground, or a projectile moving according to the rules of physics. On a server, the Role will be ROLE_Authority, which makes sense since that actor is currently being evaluated on the authoritative server. The RemoteRole of that actor will be set to any of a variety of roles, defined below. On the client, the Role and RemoteRole will be reversed. On the client, the RemoteRole will be ROLE_Authority, and the Role will be one of the other role types. Let's go through the various roles (which will be set in the RemoteRole default properties), in order of increasing 'control.'

ROLE_None
This role is probably the simplest. It simply tells the server not to make this actor relevant to the client. No information will be sent about it, and it will exist where it was created only. If it was created on both the client and the server (via a simulated function, described later), and given a Role of ROLE_None, then it would exist both on the server and on the client, and they would both operate independently of each other.
ROLE_DumbProxy
This role is used for objects that don't move much, yet still need information about them updated to the client. The server does this by sending periodic updates about this actor's location and velocity to the client. If the actor has any sort of logic to it, with Physics, for example, it's much better to use the following role.
ROLE_SimulatedProxy
This is used for anything that should be simulated over the network, via prediction. Take a rocket, for example. It always travels in a straight line, and is an ideal candidate for SimulatedProxy. By the same token, UT can predict the falling physics clientside, and so grenades, and falling people are also good candidates for this role. Anything that can be predicted clientside because of Physics or clientside physics should use this Role. All Bots and PlayerPawns use this role as well, since when a player is running, he's more than likely to continue to run. It's the best prediction method that can be used for unpredictable players. The only exception to this is the playerpawn you yourself are playing as.
ROLE_AutonomousProxy
This is used for you. When you play online, you yourself should be treated differently from all other playerpawns. You don't want your own self being predicted based upon the server's expectations. Rather, you want to control yourself and tell the server where you are moving. With this Role, that's easily possible. Many things that should only be done for your own playerpawn, like server-corrections of your location when you get lagged out, are only done with this role.
ROLE_Authority
This role is different from the others in that it is always the Role on the server. On the server, all Roles will be ROLE_Authority, and the RemoteRole will be one of the above. On the client, the reverse will be true. This role doesn't have any real significance, beyond it's use in replication statements, described below.

General Replication

For each actor that is deemed to be relevant to a particular client, the server needs to determine what subset of its variables will be sent to the client. The most obvious rule is to only send variables if they change. Unfortunately, that rule alone is not enough to fit data over a modem. Instead, the server has to further whittle down its list of variables, and it does this through replication statements. These replication statements are executed for each client, for each relevant actor to that client. When a subset of the variables of a subset of the actors are sent over the network, only then can it be fit on a regular modem. But how can a client operate without all of the information in the game? Once you stop and think about it, it's not quite that unthinkable. Do all of a Bot's AI variables need to be replicated to the client? Only the result of the AI needs to be sent, which basically consists of the same thing for any other Pawn in the game. Also, depending upon the RemoteRole, different things are replicated. Some cause the Location to be updated periodically as a poor man's simulation of its motion, while another role causes the physics to be replicated, and the location not to be, creating true client-side simulation of the actor's motion.

No Recursive Relevancy

Please note one important point that can easily be overlooked. Relevancy is not recursive with replicated references to variables. Let's say that Actor A contains a reference to Actor B in Property C, and Actor A replicates Property C (currently set to Actor B). Let's also say that Actor A is relevant, and Actor B is not. (Don't worry, there's only three letters in this example.) In this example, Actor A is relevant, and so it's Property C variable will be replicated to the client. Now what does the client know? The client knows about Actor B through Actor A's reference, but Actor B is not relevant. All of Actor B's variables are not checked for replication. The client only knows about Actor B, which really is of no use whatsoever, since the variables are not replicated. I initially thought that replicated variables to actors caused those actors to be relevant and parsed themselves for replicated variables, but that view is false. An actor can only be relevant according to the rules stated above, which make no provision for a reliable reference to them from a relevant actor.

Replication Checks

When you think about the number of clients in a server, and the number of relevant actors for each client, and the number of replication checks on variables for each actor, there's a large number of such checks. Special care should be taken when implementing replication statements. As each conditional is evaluated, you should be considerate of the server's limited processing ability. Don't call functions from within replication statements, as function calls are much too slow for replication statements. Along the same lines, you should try to keep your checks as simple as possible, only evaluating a condition if its necessary. Finally, note that Epic had a problem with replication checks taking too long for some important actors like Actor or Inventory, both of which replicate many variables. To alleviate the situation on servers, Epic moved the checks to native code. That's why you will see the 'nativereplication' on a few of the Engine classes. Any variables being evaluated in those classes will be covered by the nativereplication code, making any UnrealScript replication statements useless in that class, (except as a form of documentation for UnrealScript programmers.) Any variables that are not defined in a nativereplication class, (defined in a non-nativereplication subclass or superclass,) will be replicated via the unrealscript definitions. Despite the fact that the nativereplication checks are in C++, the UnrealScript checks that remain in those classes are still accurate, and a good guide to go by in determining problems with replication, and ways around it.

Special Replication Variables

When writing replication conditionals, there are a few things you should be aware of. During replication, a few helpful variables are set for your use in evaluating whether it should be replicated. These variables are defined in actor, and are:

bNetInitial
true if this is the first time this actor is being replicated across the network. Useful for variables that differ from the defaultproperties, yet will not change over the life of the actor.
bNetOwner
true if the player we are replicating to owns this actor directly.
bSimulatedPawn
true if the actor is a pawn (or a pawn subclass) with Role == ROLE_SimulatedProxy. In other words, true if it's a pawn that's not the client.
bDemoRecording
bClientDemoRecording
bClientDemoNetFunc
used for demo recording purposes.
bNetRelevant
bNetSee
bNetHear
bNetFeel
Not used anymore, never even set.

NetUpdateFrequency

NetUpdateFrequency is another variable useful in replication. It effectively causes an otherwise relevant (not useful when the actor is not relevant) actor to be relevant NetUpdateFrequency times per second. This is useful when the data changes frequently but you only want periodic updates. For example, PlayerReplicationInfo contains a lot of data about the client. Stuff like the various player's pings may change quite frequently, and having the client keep track of such information would be quite a network hog. But since PlayerReplicationInfo has a NetUpdateFrequency of 2, it is only updated twice a second, which is much nicer for that player's bandwidth. The list of the current NetUpdateFrequency's for all UT classes are listed below:

Actor | 100 Hz (times per second)
ZoneInfo | 4 Hz
GameReplicationInfo | 4 Hz
PlayerReplicationInfo | 2 Hz
Inventory | 8 Hz

Reliable versus Unreliable

Another optimization used in networking is the difference between Reliable and Unreliable data. In the case of variables, all data is reliable. It is all guaranteed to reach the client, even if it arrives in the wrong order. (Pawns however, have code that prevent them from appearing jumpy, although the effects of this can still be seen at times when the player bounces back and forth in a somewhat laggy game.....location updates are being received out of order.) Functions however, exist in both reliable and unreliable forms. A reliable function, like reliable data, is guaranteed to reach the client. An unreliable function however, is sent to the client, but it is not guaranteed of reaching the client. Something that sends messages to the client, like BroadcastMessage or BroadcastLocalizedMessage, are reliable to ensure that the client gets the message. Something like a client's update to the server about its position need not be reliable, however. Since the client sends these update requests to the server every single tick (in ServerMove, if you're wondering), it does not matter if they all reach the server. And since each update is timestamped, the server knows which ones to regard because they are out of order or lagged. And so, the server can be assured of getting updates from the client, while not requiring that they ALL be sent. A reliable function is repeatedly sent over the network until the client acknowledges it. This can lead to a one second delay or more if it has to try to send the message once or twice. Since you don't want to bog down the network connection with reliable updates about where the client is looking or moving, unreliable is best in this situation since the server only needs to get "most" of them to work great.

Writing Replication Statements

There are a few useful things to know about when writing your own replication statements. First, you cannot override replication statements. If a replication statement exists in a parent in regards to Location, Velocity, some function, or another variable you want to change the conditions for...you can't. Sorry. Instead, you have to mold your actor into fitting the requirements so that it's property or function will be replicated. Usually you can accomplish this by setting a variable or two (you can't set the "const" ones which are set natively of course), or by fiddling with the RemoteRole until it matches up. However, don't go around doing that blindly, or you're sure never to succeed. Instead, keep reading, and you will discover (hopefully, if I do it right :), exactly what each of the Roles are for, and what side effects they cause. Next, keep them simple. We already discussed the importance of not doing anything overly complicated, and that rule should be adhered to. Second, use the bNet* variables if possible. These variables, like bNetInitial, bNetOwner, bSimulatedPawn are quite useful, and are gratis. There is no additional CPU requirement to use these variables, as they are set for you automatically. Another very important thing to hinge your variables on is the Role and RemoteRole. "if (Role == ROLE_Authority)" would cause that variable/function to be replicated from the server (where the Role equals ROLE_Authority) to the client. Something like: "if (Role < ROLE_Authority)" would cause the variable to be replicated from the client (where the Role is less powerful than ROLE_Authority) to the server. Checks can also be performed to do various things depending upon if the Role/RemoteRole is a SimulatedProxy or a DumbProxy. The best place to find examples of these more intricate checks is in the Engine classes, particularly Actor, Pawn, and PlayerPawn. It should also go without saying that you should not change anything in a replication statement. Doing i++ in a replication statement causes i to change unpredictably as it is being replicated, which is not something you really want to do. And finally, as the last word advice, the server checks all incoming data to be sure it is legitimate. If the client replicates something (a variable or a function) to the server, the server will exchange the Role and RemoteRole variables temporarily, and evaluate the replication condition to see if the other end had a legitimate reason for sending that data. If the check fails, then the data (variable or function call) is discarded. That means that when you are writing replication statements, make sure that the server also has all the data needed to perform the replication check. Otherwise, it will never be processed or accepted by the server.

Variable Replication

Variables are one type of data that can be sent through replication statements. The other is function calls (RPC, if that helps). Here, we'll be discussing how data is replicated from the server to the client, and vice versa. There's a lot of little things that server to complicate it more than the replication described above. As I already stated above, all variables are considered reliable, so the unreliable versus reliable discussion is irrelevant here.

Newly Relevant Actors (Spawning)

When an actor becomes relevant to a client, it is spawned on the client, with all the defaultproperties of the actor. If the server set variables immediately after the spawning of the actor, (before the relevancy checks), then those variables will be sent to the client as an 'addendum' of sorts, assuming those variables meet the replication statements. The server will send any variables that differ from the defaultproperties. Things can get hairy though, when the server has a different idea of an actor's defaultproperties than the client does. Initially, the defaultproperties on the server should match up with what the client has. If a defaultproperty is changed on the server, that change is not replicated to the client. You must change it in a simulated function in order for that to occur. However, what happens if the actor becomes irrelevant? In that case, bad things happen. When the actor becomes relevant again, the default spawned actor on the client will have different defaultproperties from the server. When the server then proceeds to perform the checks on what to replicate, it sees that the default var is the same as that var, and so that var is not replicated. The client then never gets data, and so has the REAL default variable, of a fresh actor. That variable can be incorrect, and cause strange behavior to occur.

As an example, for a particular class-based mod, a programmer (not me, this time ;-) had set both the Mesh and Default.Mesh to the playerclass that the player had chosen. Players however, go in and out of scope, to save on network bandwidth. Normally they are only relevant when you can see them, and for about three seconds once them disappear from view. Let's say the player changed their playerclass at that point. Or say they changed their class at the start of the game while the round has not started and they are invisible, and thus not relevant. When they did become relevant to the client, because they turned a corner, or because the round just started and they are spawned and made visible, the Mesh == Default.Mesh, and so the Mesh is never replicated. The skin however, was still replicated normally. To clients in the game, they saw the player as the original mesh, with a inappropriate skin that was intended for another model. Like I said, strange behavior, that can be hard to trace down. The way to handle this, is to not set the Default variables unless you are really know what you are doing. Just setting the Default.Mesh because it feels right will only cause problems. In this case, the Default.Mesh was not needed for everything, and removing that assignment caused everything to work fine.

A Time for Replication

Replicated variables are only replicated at the end of each tick. That means that if you change the variable repeatedly during a loop, or some other block of code, only the final value will be replicated. If you change a variable many times during a tick, and change it back to its original value when the tick completes, then no variable change will have been seen, and no network bandwidth will have been spent.

Client-Server Replication

Another quirk to be aware of is that client-server replication exists ONLY for your own playerpawn. That means that if you want a variable replicated from the client to the server, it needs to be done in your current PlayerPawn (or one of its parent classes). (You can use function replication to get around this limitation however.) Other playerpawns in the level are not the one that you currently 'possess', so their variables will not be replicated to the server. Just be aware of that when trying to replicate your variables and they aren't working. :) Thinking about it, it makes sense. What right does the client have to send any information to the server about another playerpawn, or some inventory item? The client is only concerned with variable changes that the player himself (or herself) makes, and thus those are the only ones that are sent to the server.

Replication Only When Necessary

Further optimizations exist for variable replications as well. A variable will only be replicated if the server thinks the client has the incorrect version compared to the server's latest version. This usually happens when the server changes a variable, and it knows the clients do not know about such a change. (They would if the function that changed them was simulated and was called clientside, meaning that you technically would not need to replicate that variable. This is explained later.. :) This means your code can change stuff clientside, and it will not be written over by server-side data until the server's data changes. As an example, I used this technique to implement a simple little static LOD back in the Unreal days before Epic introduced their realtime LOD. The client determined how far away the player was, and switched in variously detailed models depending on the distance. This allowed more models onscreen at once. And in multiplayer games, the client could change the mesh to the various LOD meshes, and it would work fine. Since the server never saw a change in the server's mesh (assuming it was a dedicated server), the client could change the LOD mesh without any problems. When the server did change the mesh however, the client would get a new mesh variable sent to it, and so it would have to then change it again. As a bragging aside, it even modified the intensity at which is applied LOD depending upon the framerate. ;)

Replication Data Approximation

Another optimization is that of how Unreal sends vectors, rotators, and arrays across the internet. The rules for this can best be described from the Unreal Tech page's Networking document, and I've copied it here to keep it in context:

  • Vectors and Rotators: To improve bandwidth efficiency, Unreal reduces the accuracy of vectors and rotators slightly, a process known as quantizing. The X, Y, Z components of vectors are converted to 16-bit signed integers before being sent, thus any fractional values or values out of the range -32768..32767 are lost. The Pitch, Yaw, Roll components of vectors are converted to bytes, of the form (Pitch8)&255. So, you need to be careful with vectors and rotators. If you absolutely must have full precision, then use int or float variables for the individual components; all other data types are sent with their complete precision.
  • General structs are replicated by sending all of their components. A struct is sent as an "all or nothing" type of thing.
  • Arrays of variables can be replicated, but only of the size of the array (in bytes) is less than 448 bytes.
  • Arrays are replicated efficiently; if a single element of a large array changes, only that element is sent.

Variable Replication Examples

Now would probably be a good time to go through some important examples of replication and how it is used with variables, to give you a better idea of how things work, and to help give examples for your own adventures in coding.

Let's take a few examples, and describe exactly what they do. We'll start off with the easy ones, and gradually work our way up in complexity. The following examples are all taken from Actor, unless specified otherwise.

In PlayerPawn:
reliable if ( Role < ROLE_Authority )
        Password, bReadyToPlay;
This here shows where your Password is sent to the server, when trying to join passworded servers, or to log in as an admin to that server. The server needs your password in order to validate it, and this code sends it to the server. Let's evaluate this check both on the server and on the client. Server: On the server, Role == ROLE_Authority. Looking at the conditional, it can easily be shown to be false, and so the Password is not replicated server-side. This means that the server does not send the Password to the other end of the connection. Client: Since on the client, the Role is not ROLE_Authority (remember it's only Authority on the server itself), this replication check evaluations to true on the client. And since variable replication only works in your current PlayerPawn, it will be sent to the server for yourself alone. (It makes sense not to send other's passwords, doesn't it? ;)
This also shows how bReadyToPlay, which is used in Tournament style games, where everyone has to click to start the game. Note that this is only sent for yourself, since the client can only replicate variables to the server if they are part of it's own playerpawn actor.
unreliable if( Role == ROLE_Authority )
        Owner, Role, RemoteRole;
This ensures that the owner of an object is always replicated to the client. Remember that the owner's variables themselves are not replicated, (because there is no recursive replication,) but the actor itself is. This means that simple comparisons "if (PlayerPawn == Owner)" will work fine because the reference to the Owner is replicated to the client. Remember that the unreliable versus reliable makes no difference in UT, as they are both treated equivilently. They may have had an effect at sone point during the Unreal 1 days, but they no longer play a factor in development. Don't let that confuse you.
Replicating Role and RemoteRole may seem strange at first, since they should be reversed on the client. However, there's native code that causes that switch to be made. On the client, it will ensure that those two variables are reversed, so that RemoteRole is ROLE_Authority. You may wonder why they are even replicated in the first place. While the client never has any direct use for these variables in the code, there is one easy-to-overlook place where they are vitally important: Replication Statements. When the client is evaluating whether it needs to replicate a certain function call to the server, or a playerpawn's variable to the server, the client needs accurate copies of what Role and RemoteRole are. Without those, it would be unable to make the necessary decisions on what to send to the server. And since the server checks the validity of the replication data sent to the server with Role/RemoteRole, the client needs the latest copy in order to successfully replicate that data.
unreliable if( bNetOwner && Role == ROLE_Authority )
        bNetOwner, Inventory;
Inventory is the head of the linked list that lists the entire Inventory for the Actor (usually only utilized with Pawn and PlayerPawn). We want the inventory to be replicated to the client, so that he knows what Inventory he has, to display on his HUD, and stuff (makes sense, right?). Simply replicating the head of a linked list (where each object points to the next in the list) is not enough however. Each actor must itself be relevant (satisfied by the criterion that it must be owned by the current playerpawn), and each link itself must be replicated. And since Inventory subclass Actor somewhere in the chain, Inventory also has a replicated Inventory variable. And that's how you are able to see your Inventory client-side. And since I don't need to know the full Inventory list of what every other player in the game has (the current weapon and the shieldbelt effect are transferred via other means), the Inventory will only be replicated if the client is the owner.
The other variable in the above replication statement is bNetOwner. Since this is set natively on both the client and server, this variable does not need to be replicated. It could be argued that it adds a tiny amount to bandwidth, but its effect is probably negligible. Perhaps it will be removed in a future patch.
unreliable if( DrawType == DT_Mesh && Role == ROLE_Authority )
        Mesh, PrePivot, bMeshEnviroMap, Skin, MultiSkins, Fatness, AmbientGlow, ScaleGlow, bUnlit;
Here we see that all these mesh-specific variables are ONLY replicated if this actor is currently being displayed as a mesh. If it's a sprite, or a brush, or even no drawtype at all, there is no reason to send these variables.
Now let's get into some of the more complex variable replication statements...
unreliable if( RemoteRole == ROLE_SimulatedProxy )
        Base;
Here we see a slightly more complex replication statement, that does not involve Role == ROLE_Authority. Here we see that the current Base (set via SetBase) is only replicated if the actor is set to be a simulated proxy. If you set the actor to a DumbProxy, you'll see no Base change clientside, and instead will get the jerky Location updates that the server sends to you, (more on this later). So if you are using SetBase, make sure it's a SimulatedProxy, or if it's not a SimulatedProxy, use something other than SetBase. :) Or if you need both SetBase and a SimulatedProxy, the Base will not be replicated for you. You'll have to work out some other mechanism to do that, probably a simulated function that sets the base, so it is run on the client, (more on this later, too.) You might still have troubles when the actor gets its simulated function called while the actor was not relevant. This results in the simulated function never being called clientside, and then when the actor does finally become relevant, it's as if that function was never called (and the base isn't set), which will result in those things affectionately referred to as 'bugs.' You can make the actor being attached (and what it's being attached to) bAlwaysRelevant so that the simulated functions will always be called, but that might be a bit too harsh on network bandwidth. :)
unreliable if( RemoteRole == ROLE_SimulatedProxy && Physics == PHYS_Rotating && bNetInitial )
        bFixedRotationDir, bRotateToDesired, RotationRate, DesiredRotation;
This one is still relatively easy, but it's getting more complex. Here we have similar logic to what was seen above, with the server only sending these variables to the client if the client is a SimulatedProxy. However, since all these variables apply ONLY to PHYS_Rotating, there is no need to replicate these variables to the client if the client is not using PHYS_Rotating. And finally, a very important clause at the end is the bNetInitial one. This states that these variables will only be replicated to the client when it is being replicated for the first time.
unreliable if( bSimFall || (RemoteRole == ROLE_SimulatedProxy && bNetInitial && !bSimulatedPawn) )
        Physics, Acceleration, bBounce;
Here we have some of the interesting variables replicated. We see that if the bSimFall is set to true, it will replicate the Physics to the client. This is used when tossing weapons from your inventory. When they are tossed, they require a Physics change from PHYS_None while sitting in your Inventory to PHYS_Falling as they fly through the air. The then get set back to PHYS_None when they land on the ground. All these Physics changes are accomplished by setting bSimFall at the key points during the TournamentWeapon's life. It is set to true when it is thrown from the inventory, to capture the change, and left on until it hits the ground, where it changes Physics again. After it finally hits and has its physics reset, bSimFall is set to false so no further Physics changes occur. Looking at the second half of the statement, we see that the Physics is replicated ONLY if it's a SimulatedProxy, it's the first time this actor is being replicated over the internet, AND it's not a simulated pawn. The bSimulatedPawn variable is set to true if it's a Pawn with a RemoteRole of ROLE_SimulatedProxy (who would have thought? :) This means any changes to the Physics of a SimulatedProxy non-pawn actor before it is replicated will be replicated to the client. The Physics are never replicated for pawns. Rather, the code for their physics is hard-wired into the code to cause them to be pushed to the ground. Basically, when a pawn jumps, the server sets his vertical velocity so that he travels upwards. That Velocity is then replicated to the client (described below). The client then checks if the pawn is a player (eg: a bot or a playerpawn), that they are currently unable to fly (set via the Pawn's bCanFly variable), and that they are not in a water zone (since that involves different gravities and physics). So in fact, the Physics for a pawn is never replicated to the client, it only appears to do so. If you are attempting to create alternate physics with the playerpawn, you will need to ensure that you set bCanFly to true so that the native code does not enforce the falling Physics upon the player when he's on the wall or in the air. You must then implement the alternate means of transportation yourself.
unreliable if( !bCarriedItem && (bNetInitial || bSimulatedPawn || RemoteRole < ROLE_SimulatedProxy) && Role == ROLE_Authority )
        Location;
Here we see another important variable, Location, and it's replication. We see that it is not replicated for carried items. This is useful in the case of Inventory. When a player is carrying it, there's no reason its location should be replicated, since it isn't used for anything. replicating a player's entire inventory would be quite the strain on network bandwidth. Let's look at the next section of the statement. The location is replicated if this is the first time the actor is being replicated (assuming the other parts of the conditional are true). This is very useful, since all pawns will be spawned in different locations when you enter the game, and rockets will need their start locations set when they spawn out of a rocket launcher, etc. The location is also sent if this is a bSimulatedPawn. This helps correct any errors that may occur in replicating pawns. Since a pawn can change direction, and a client may not always know about it (due to lag, etc), this location resetting is the only way in which the locational updates can be 'corrected'. Note that this is not used to correct your own location when you experience lag. When that happens, you are an AutonomousProxy, and functions specific to PlayerPawn handle that (namely ClientAdjustPosition). For example, PHYS_Walking is not like PHYS_Projectile, where the position can be predicted with great accuracy. PHYS_Walking just means "keep them attached to the ground", basically, The client's only updates (without location) would have been their velocity, which can easily lead to errors in the player's movements over any significant amount of time. This location is used as a correcting factor, making sure the client's view does not straw too far from where he expects the player to be, while at the same time keeping the velocity's replication so he can be predicted inbetween server updates. The other option for allowing the Location to replicate is that of where the RemoteRole is less than a ROLE_SimulatedProxy, namely, a ROLE_DumbProxy, since the ROLE_None prevents relevancy in the first place. DumbProxies get periodic updates from the server every few ticks, and would create a jumpy effect in netplay. It was the cause of a jerky puck in the hockey mod I attempted awhile ago, although I knew nowhere near enough to fix it at the time. :) A SimulatedProxy would not get sent Location updates, since it would be predicted through the use of the Velocity and the current Physics. Since DumbProxies aren't simulated client-side to achieve smoothness, they only get the Location updates. I'm going to clear this all up after the examples of the various replicated variables.
unreliable if( !bCarriedItem && (DrawType == DT_Mesh || DrawType == DT_Brush) && (bNetInitial || bSimulatedPawn || RemoteRole < ROLE_SimulatedProxy) && Role == ROLE_Authority )
        Rotation;
Here we see another important variable, Rotation. This also has the same !bCarriedItem clause, for the same reasons as described above. The rotation is also only replicated if this actor is a mesh or a brush. Since sprites always face the player, replicating their rotation is useless. The bNetInitial also causes the rotation to be replicated the first time through, (again, assuming if the other conditions are true,) since rockets need to be facing in the right direction when it has them flying through the air. Their velocity determines their direction of movement, but the direction they are facing which is equally important, is determined by their rotation. The rotation is replicated if they are a simulated pawn (every playerpawn and bot in the level except your own self). This is so you can see what direction the other people are facing. The ViewRotation (which determines where the client is looking), is sent to the server via ServerMove, where it is translated into a rotation. it is this rotation that is then replicated to the clients. And finally, if it is a DumbProxy (the only valid one less than SimulatedProxy), it also gets the rotation updates. Rotation updates do not need any interpolating between updates like location does. Location lag is much more noticeable when the player is moving quickly, but you never really notice Rotation lag. Besides, there is no real way to predict or forecast rotation. It depends entirely upon the other user's mouse.
unreliable if( bSimFall || ((RemoteRole == ROLE_SimulatedProxy && (bNetInitial || bSimulatedPawn)) || bIsMover) )
        Velocity;
Here's one of the last important variables with a complex replication statement. The velocity is replicated if it has bSimFall set, (used when throwing weapons from your inventory). The PHYS_Falling alone isn't enough. It needs to know exactly what it's initial velocity is when it is launched from the pawn. And no, bNetInitial will not work here, since it's not the first time it's being replicated. It's existed as a weapon for quite some time. It's just for the initial velocity of when it's being thrown from the player that we want updates. Moving along, we see that SimulatedProxies get their Velocities replicated if it the first time on the replication channel, for newly spawned rockets, or for grenades, or shock projectiles, etc. SimulatedProxies also get their velocities replicated if they are a simulated pawn, as all the various pawns need their velocities replicated so that they can be predicated locally. And finally, movers get their velocities replicated, so that the client can accurately predict the mover's movement locally. In the early Unreal 1 days, mover's velocity was not replicated, and so the client got periodic update locations because it was a DumbProxy. This resulted in very jumpy movers in netplay, something that was fixed for Unreal 224+.
unreliable if( DrawType == DT_Mesh && ((RemoteRole <= ROLE_SimulatedProxy && (!bNetOwner || !bClientAnim)) || bDemoRecording) )
        AnimSequence, SimAnim, AnimMinRate, bAnimNotify;
There are a few more variables here, all of which relate to animation. These variables are only replicated if it is currently being drawn as a Mesh. If we are recording a demo, then the animations are always sent. Otherwise, it checks the somewhat confusing conditional. If the actor is a DumbProxy, and the player is not the owner of this object, and bClientAnim is not set, then it replicates the animation variables. In the case of weapons, you see those animations clientside, and so the animation variables do not need to be replicated from the server. That is because all TournamentWeapons have the bClientAnim set to true, indicating that their animations are handled clientside. If the animations are not handled clientside, and the actor is a dumb proxy, then it will send them from the server. SimulatedProxies, which include pawns and rockets and other projectiles, are all simulated proxies, and so they do not receive animations from the server. Instead, the client animates them with its client-side prediction. In the case of pawns, this is handled internally in the engine (for another tutorial ;), and you need not worry about it.

Role and RemoteRole Summary

Hopefully this intricate look into some of the more complex and confusing variables has helped you to grasp the concepts of replication some more, and realize many of the differences between the various roles. However, with the above knowledge in mind, I'd like to do a little re-cap, emphasizing the use of dumb, simulated, and autonomous proxies, and help give you a clearer idea of when each should be used.

ROLE_Authority - Again, this is the Role for all actors on the server, and is the RemoteRole for all actors on the client. It basically means that I'm the authority on this actor. This is the only one variable that Role is set to, server-side. The remaining ones are all used for the RemoteRole when on the server.

ROLE_None
This basically says: Never make this actor relevant. This prevents replication conditions from even being run, and so does not factor into any of the replication statements.
ROLE_DumbProxy
This role is used for simple actors that require no real client-side prediction. They don't need any Physics prediction, but they only need to be relevant to the client to get their variables replicated. This is used for all Inventory actors when they reside on the ground, which prevents any higher-bandwidth SimulatedProxy stuff, but yet allows you to see all the stuff you need for the inventory actor. If you do try to move this actor, the client will get periodic updates, usually around every half-second or so on a regular connection. This creates quite a jumpy effect if you are using DumbProxy with a particular Physics type, since it really isn't intended for that. Rather, the Location updates are useful for when moving the actor across the level with a flag respawn, etc. The same is done with rotation updates, with periodic changes coming in to the client every so often. This role also causes animation updates to be sent from the server to the client, unless the client specifically tells it not to. In summary, an actor with this role is force-fed data from the server. It's intended for actor's that don't move (except in jumps like transportation, respawn, etc), yet are still relevant.
Other quirks: There's a few quirks that can have a significant effect on your netplay development. DumbProxy actors do not have a variety of events run clientside. Simulated Tick(), Timer(), and state code, along with the physics calculations, are not performed on the client of a DumbProxy actor. They are supposed to be a dumb proxy actor that gets data sent over the net, and so these events are not called. One exception to the above rule is that physics are performed clientside for DumbProxy actors if the actor has a falling physics, which allows tossed weapons to fall correctly in netplay. In an early attempt at the weapon in the tutorial at the bottom of this document, I attempted to create a client-side physics that would combine with the location and rotation updates that were inherently sent via the DumbProxy role, but the client would not run my Tick()-based physics calculations, and so that idea had to be thrown out the window. :)
ROLE_AutonomousProxy
This is used for things that the client directly controls. In most cases, this will only be used by the playerpawn. This RemoteRole value should only be set for the one particular player, and it should be a SimulatedProxy for every other client in the game. The player for which it is AutonomousProxy is the player possessing that particular PlayerPawn. When it is set to AutonomousProxy, it appears to be a SimulatedProxy for everyone BUT the owner of the proxy or the instigator. This ensures that your PlayerPawn looks like a SimulatedProxy to everyone but yourself. Note that this technique is also used with the guided redeemer, to ensure that it works the same way. Having the server tell you where your guided redeemer is flying would not be appropriate. Rather, you want to tell the server where your guided redeemer is. While AutonomousProxy doesn't make this just 'work' for you, it does differentiate you from the other people viewing your redeemer, which is what is needed to have it act differently for you, compared to everyone else.
ROLE_SimulatedProxy
There are two different things that can happen with this particular type. It depends on whether the actor with this role is a pawn or not a pawn. I'll discuss the latter first.
Non-Pawn ROLE_SimulatedProxy
This one is basically the opposite of DumbProxy. It expects full client-side prediction of the actor, given initial values. It's like extrapolating out a curve given some data, where the current Physics is the curve fit, and you have initial data available to extrapolate from. ROLE_SimulatedProxy gives you an initial Location, Rotation, and Physics. It then keeps you updated with the Velocities, should they change. These variables should enable the client to perform full client-side prediction on this object, assuming it continues along the physics prediction. In the case of PHYS_Falling and PHYS_Projectile, this is the case. There can be no aberration form these behaviors, (unless you play around with the Physics variables bBounce and such, which are very useful in prediction.) Perhaps I'll explain Physics in more detail in another tutorial. Perhaps. ;) Finally, for this role, you also get animation updates, assuming the client is not the owner and it's not set for client-side animation. In summary, this Role is for actors that smoothly predict their data on the client.
Pawn ROLE_SimulatedProxy
When ROLE_SimulatedProxy is combined with Pawns, a different sort of simulated proxy is created, that act differently in netplay. Pawns are one of the most complex actors in terms of replication, because of their need for clientside prediction, yet inherent unpredictability in their movement. There is no way to duplicate this behavior except by subclassing pawn, so don't expect to achieve it in your projectile subclass. A SimulatedPawn gets the best of dumbproxy and simulatedproxy. It gets velocity updates for the clientside prediction, while at the same time getting location updates from the server to 'readjust' the player's locations. You might then wonder why the pawn does not jump when a new location update comes in. Again, there is native code that causes the actor to smoothly head towards the location given by the server if the location position is too far off from the player's real position. This again ensures seamless movement of player's while keeping them accurate to the server's version. All non-players will get by with velocity-only client-side prediction. No physics will be taken into account for these pawns. This is because some non-players can be PHYS_spider, or a variety of other physics that don't work with the following always-walking/falling prediction. Only players (bots and playerpawns) get the special client-side prediction to have falling/walking physics. This physics is an assumed physics, which is accomplished by applying the zone's gravity if the player is not on the ground. This logic will be bypassed if the pawn's bCanFly variable is set, which frees it of the clientside physics, but must be accounted for in your code, since there is no physics replication in pawns. This logic is also bypassed if the pawn is in a water zone, which also differs from the default walking/falling physics. In water zones, actors are predicted using velocity alone, which is sufficient with the low amount of gravity that exists in those zones. The actor's get their locations 'adjusted' anyway, so it doesn't make any real difference in the long run. Finally, pawns get rotation updates. Since rotation (which is directly based off the ViewRotation, or the direction the player is looking) can change quite radically, no prediction is done with it. Instead, the player's rotation is adjusted as new player rotation information comes in from the client. Animation is handled the same as any other non-pawn simulated proxy.

Function Replication, and Simulation

In a network game, functions can be called on the server, on the client, or on both. Sometimes you will want one situation, and sometimes you will want another. Function replication and simulation both achieve different pieces of these goals. Despite what may at first seem like two different topics of discussion altogether, they are actually quite related at their root. I will discuss them together, and then finish with a clarification of their differences so that each can be understood clearly.

Internally, the Unreal Engine uses a very simple system for its function stuff. It calls a function to determine if it can call an UnrealScript function on that machine. if it can, it does, if it cannot, then it does not. That's all that simulation and replication entails, and the only additions to this system are the origin of UnrealScript simulation, events, (which will be discussed later), and the function replication itself (much of which you know already.)

Rep/Sim Function Rules

I will first present the basic simple rules to determine if a client or server is able to execute the function locally. The following conditions will determine whether that happens. Again, if a condition matches, then the checking stops there, and it executes locally depending upon the resulting clause of that condition.

  1. If it is a static function, it can be called on that machine.
  2. If we're on a standalone server, it can be called on that machine.
  3. If it's not a replicated function, then go to step 10.

(The rest apply ONLY to replicated functions, per condition three.)

  4. If we are the server, and there is no parent PlayerPawn to this actor, (at any point in the parent hierarchy,) or if the player does not have a connection (listen servers for the player on the server,) then it is executed locally.
  5. If the replication condition is not met for the current machine, (meaning that it was replicated to us, or that it is not a valid replication statement), then go to step 10.

(The rest apply ONLY to replicated functions where the replication condition is met, and it is a valid function to replicate.)

  6. If it is an unreliable function, and the connection (server-client or client-server) is saturated, then 'pretend' it was executed remotely, (eg: do not execute it locally.)
  7. Replicate the function, and then do not execute it locally.

This last step is only used if it is called upon by the above steps.

    1. If we are on the server, then it can be called.
    2. If we are on the client as an AutonomousProxy, it can be called locally.
    3. If we are on the client as a DumbProxy or SimulatedProxy (NOT an AutonomousProxy,) and we are a simulated function, then it can be called locally.

While this may seem complex, it accurately describes in every detail how Unreal does it's function handling, and RPC (remote procedure call) nature. Hopefully, in the next paragraph or two, I'll be able to simplify it into a few simple rules.

Rep/Sim Function Rules Restatement

In order for a function to be replicated to the other end of the connection, it must be all of the following:

  1. Owned by a network PlayerPawn at some point it it's parent hierarchy.
  2. It must be a reliable function, or an unreliable function with available bandwidth.

In order for that replicated function to actually be executed on the other end of the machine, it must pass rule number 10. Additionally, if we are on the client, it must meet any of the following rules.

  1. A static function.
  2. A simulated function.
  3. In an actor with an AutonomousProxy Role (a local PlayerPawn or local GuidedWarhead on the client.)

The above rules need to be passed for ANY function that is executed on the client, whether it is through simulation or replication.

Rep/Sim Function Summary

With those rules in mind, I'll try to summarize the whole situation below.

On a server, every function is executed, unless it is a (client-server) replicated function and meets the checks above. So you can be assured of all your functions running on the server, unless you specifically tell them not to.

On the client, every function has to originate from a 'source.' A source can be a server-client replicated function, an exec function, or an event. Events, while not covered previously, are quite simple. An event is any function that is called from native code. Events happen both on the server and on the client. The server does not directly tell the client to execute the event, but the client knows to execute the event based upon the game state (colliding actors, hitting a wall, a timer event, ticking of the game state, etc). If that event is simulated, then it can also serve as a 'source' of clientside function calls. A source can call any function it wishes, assuming it meets the client-side execution conditions, which can then call any...and so on.

What happens if a function is called, but doesn't meet the conditions for execution, either because it was replicated to the other end, or because it does not meet the conditions for running client-side. In that case, it is as if the function never ran in the first place. The return value of such a function is 0, "", or None, depending upon the context. Any out parameters defined by the function are passed back exactly as they were entered. Relying on the result of a function that is never executed is the source of many accessed nones that appear only on the client. Exec functions (functions that can be bound to keystrokes) naturally evaluate on the client. Again, remember to make it simulated, (unless you are in an AutonomousProxy, like a PlayerPawn subclass.) In some cases, you may want to have it replicated to the server, as in the case of a Server-Administrator command (there are plenty of these defined in PlayerPawn.) Exec functions can be replicated to the server, the same as any other function can.

Spawning Within Simulated Functions

There are other interesting hidden behaviors that may not be immediately apparent. For example, because of the requirements that an actor be owned by a playerpawn at some point in its parent hierarchy, a function can only be replicated to a single player in the game. (No, making a player owned by another player will not work. ;) Multicast function replication does not exist. You can try to get this behavior using simulated functions, but no data can be passed between the server and the client, (since they both originate on their local machine, and exist only on that local machine.) Or you can use replicated variables, which can and are replicated to all players in the game, assuming they are relevant to them.

If a spawn is performed in a simulated function (simulated functions are explained later), then multiple copies of the actor are spawned: the server, and each of the clients that the simulated function was run on. The server's version is normally then replicated to the client, so the client would see two versions. This would create strange behavior as the two became out of sync, and the client-spawned one could easily be mistaken for the 'official one' that for some reason, isn't having it's variables replicated.

If you need to do a spawn in simulated code (there are many valid reasons, like spawning effects clientside, etc), then you must account for this. If you are attempting to make clientside effects, then make sure you set the RemoteRole to ROLE_None immediately afterwards. Since relevancy is only checked between ticks, this will ensure that when that check does come around, it will not be relevant, and thus not replicated. That way, the server and the client will each have their local copy of the effects that run their course and then destroy themself. This is not useful for permanent effects, since simulated functions are not run on ALL clients, only clients where the actor containing the simulated function is relevant. That means that if the simulated function didn't run (because it's actor was not relevant at the time), then the effect will not be visible when you come into view of that effect. That is why it should only be used for temporary effects that run their course and then destroy themselves.

If however, you are spawning something that is intended to be permanent, or needs data replicated from the server, (like a crosshair dot,) then you SHOULD NOT spawn it on the client. Usually, you can accomplish this with a 'If (Level.NetMode != NM_Client)' check before you perform the spawn. This way, the spawned actor will then become relevant (assuming the conditions match), and it's variables will be replicated to the clients. If a client-side actor had been spawned, then there would be two actors, one of which would just sit there without information from the server

Networked-Function Paramater Optimizations

And finally, when replicating functions, Unreal optimizes the parameters of a function call through a few techniques. When sending a vector, (which is composed of three floats,) the individual components are rounded to integers, and thus lose their fractional values, and any values outside of -32768 to 32767. A common technique is to multiply the values before they are sent to make them scaled integers, and then dividing them on the other end back into their appropriate values, so it is almost completely accurate. With rotators, the values are scaled between 0 and 255, where the 128+ range corresponds to the normally negative range of rotator component values. Then they are rounded to ints, and sent over the network. They are then fixed back up again to their original values (except they are left as positive values, since they are equivalent to their negative counterpart that existed on the other end of the connection. One approach that applies to both vectors and rotators is to send the X/Y/Z or Pitch/Yaw/Roll values of the struct as individual floats so that complete accuracy can be maintained. And finally, for completeness, planes (which are not used much at all,) replicate their components as rounded integers.

Simulated States

Another, many times overlooked feature is that of simulated states. You probably have already seen state code, code that exists outside of functions, but in states, usually prefixed with labels. This code, when in a regular state, is executed on the server alone. But by prefixing the state statename with simulated, you can make the state code itself simulated. So the revised state declaration would be simulated state statename. Just beware that state changes are NOT replicated or sent to the client by default. However, if a gotostate is executed in a function that is run on the client (either through replication or simulation), then the client will know of the new state. Playerpawn's inherent simulation allows all it's functions to be able to control the state, but other classes would need to have simulated functions that are executed from a simulated source and chain of function calls in order to know of the state change. The current UT code makes no use of simulated states, but I thought I would include this section for the sake of completeness, in case you ever needed it.

Level NetModes and their Implications

In the Level variable, which references a LevelInfo actor and is accessible from every object, is a NetMode variable. The NetMode variable is used to describe what role or position the current instance of UT plays in the overall scheme. The possible values, and their uses are:

NM_Standalone
This is for when the game is played alone, like botmatches, the single player tournament ladder, etc
NM_DedicatedServer
This is for when the server is running alone, with no one playing directly in that instance of UT. This is the netmode for the majority of servers that are online. It can be started with 'ucc server', or by clicking 'Dedicated' when you select 'Start New Multiplayer Game.'
NM_ListenServer
When you click 'Start' in the 'Start New Multiplayer Game' window, you are starting a listen server, which is when you are playing and hosting at the same time. This causes CPU to be spent on rendering the world for you, as well as hosting the game for any connecting players. Thus, dedicated servers are preferred to listen servers.
NM_Client
When you are connected to a running UT server, no matter what type of server it is, you are this netmode.

These netmodes are usually not important as Roles and RemoteRoles can handle everything. However, when you want to execute a block of code on the client, but don't want to replicate it, these netmodes can help. For example, code is run on the client through a chain of simulation. If the chain of simulation is upheld, then you can do a 'if (Level.Netmode == NM_Client) {', then that code will be executed on the client only, or on many clients, if that event exists in many places. By combining that with a check on Owner, it is possible to ensure that it is only run on one single client. One thing that makes the whole deal more complex is that you want to ensure your code will run in standalone games, and for the guy running and playing in listen servers. For this reason, you will often see code that does 'if (Level.NetMode != NM_DedicatedServer) {', which probably does exactly what you want. Other examples include only spawning non-relevant gibs if you aren't on a dedicated server (because of the increase in CPU time). Another example is the use of spawning a gibbed head. The gibbed head needs to travel in the same, but random, direction as the server. Giving it a random velocity on the client would cause it to readjust midflight when the network-replicated data came through the pipe. Instead, the carcass head is not spawned clientside, but rather it lets the network data create the head, and give it the server's random velocity, so that it will be correctly in sync. Further uses are left to your imagination. :)

Special Properties about Special Stuff

bNetOptional Usage

You've seen bNetOptional talked about a few times. Now's a good a time as any disucss what it was intended for, and when you should use it. As was discussed earlier, any actors that have bNetOptional set get put at the bottom of the list of actors. The effect of this is that they get starved of bandwidth when the connection becomes full. If there's bandwidth available however, then they'll be replicated. They have 150 ms to be replicated, before they are forgotten about completely, and the client never sees them. When should you use these? In most cases, you'll want to use them for temporary effects that can be replicated to the client, and then allowed to complete on their own. For example, a little puff of smoke coming from a wall after you shoot it would be a good example. If your bandwidth is overloaded, either from a big firefight, or from excessive lag, then the little puff of smoke will not be seen. You probably won't notice it in either case. bNetOptional actors will not be replicated after their initial replication, either. They're conditions are evaluated only once, the first time they are executed. They are expected to complete their actions without any interaction of the server. This also saves a lot on bandwith. It wouldn't make sense to have the server continually evaluate replication checks for these actors, since that would only waste bandwidth. bNetOptional is not for everything though. An explosion sprite, like a rocket's animated explosion, is necessary for everyone in view. It's easy to miss a sprite puff of smoke in the heat of battle, but a large explosion is not something easily missed. You'll want to use the bNetOptional only for small, non-vital actors that aren't necessary. In Unreal Tournament, they are used for decals, fragments (those little chunks of 'wall' that fly off), shell casings, smoke puffs, the wall hits (the little yellow 'spark' when you hit the wall), and the respawn effects. Note that if the default lifespan is set to 0, then a bNetOptional actor will be treated just like any other actor. If the bNetOptional actor does have a default lifespan set, and it extends beyond the first 150 ms of it's lifetime, then it will never be replicated. Any request to destroy an actor will be replicated to the client regardless of at what point it exists in it's lifespan, as UT will always make sure the client destroys what the server destroys.

bNetTemporary Usage

While we're at it, we might as well cover bNetTemporary here. bNetTemporary actors are for 'tear-off replication', as someone once put it. They are replicated when they are first spawned, and that is it. There is never any further connection between the server and client in regards to that bNetTemporary actor. A bNetTemporary actor is not necessarily temporary, just that the replication of it's variables is temporary, (only once.) This is used in many places. In UT, all decals and projectiles are bNetTemporary by default. A decal is replicated to every client that it is relevant to, and then the connection is broken. this saves significantly on bandwidth. This means that if you walk into view of a scene where there was a battle that you did not witness, then you will not see any of the decals in that room. They were temporarily replicated, and so you will never see them if you weren't present for it's one-time replication. In Half-Life, decals were not 'bNetTemporary', and so were sent to every client when they came into view. This contributed to part of the lag that many experienced because of the many decals and spraypaint decals that were spawned in a game. bNetTemporary actors need to be destroyed in clientside simulated code, since a server destruction of the actor will not replicate to the client, because of it's bNetTemporary status. This is done when decals grow stale and need to delete themselves based upon client information, since the server cannot tell the client about that. Most projectiles utilize bNetTemporary. Take a razorblade, for example. It gives the client the initial velocity, and the client can work everything out from there. Since the razorblade is entirely predictable and deterministic, it can be predicted on the client with 100% accuracy. The wall it bounces off on the server.....it also bounces off the equivalent wall on the client. Because it is entirely predictable, the server only needs to send it once, and the client can figure it out. For that reason, projectiles are bNetTemporary. Problems can happen when you enter a big room that has razorblades flying around. Because the razorblades are bNetTemporary, you will not know about them. So you can walk into what seems like a perfectly empty room, and then get your head chopped off with a razorblade. However, you'll since most people do not use 360 FOV, you'll probably attribute it to just not seeing it coming. So no one ever notices that. Other projectiles like the the guided redeemer missles, or even regular redeemer missles (which can be shot down midflight) cannot be bNetTemporary because the server needs to send status updates to the client. The green globs from the goop gun need to be visible on the floor when you run into a room, (because they are sorta-long-lasting land mines,) and so they too cannot be bNetTemporary. There are other examples of where projectiles are not bNetTemporary, but I'm sure you get the idea.

PlaySound's and PlayOwnedSound's Special Behaviors

This one issue was brought to my attention when someone was trying to figure out how come a sound wasn't playing correctly in his mod, even though it worked fine in UT. After looking into it, I couldn't see how the sound was working in UT. The replication and simulation behavior was not set up for it. Turns out that it had hidden behavior, depending upon where and how it was called. In theory, PlaySound is used to have an actor play a sound. The game will determine how loud to play it, depending upon occlusion and distance, etc. UT tries to determine the 'right' and intelligent way to propogate the sound, depending upon how it was called. First, we'll cover PlaySound. It can be called in two contexts:

From a simulated function, or from a replicated-to-client function
In this scenario, the sound is being played in many places. The simulated nature means that any player that can see the actor, is getting the simulation events. So each client will play the sound on it's own, due to the simulation. In the case of a replicated function, (where it's being run on the client,) UT assumes you know what you're doing, and that you want the sound to be played on that client only. You may wonder why there is a check for a replicated-to-client function when there's already a simulated function check, (since all replicated-to-client functions need to be simulated,) but if you remember, a PlayerPawn that is operating under ROLE_AutonomousProxy can execute replicated functions that do not have the simulated prefix. This case covers those. In general, this play-locally behavior is what you want, when you call PlaySound from within a simulated function.
From a non-simulated, non-replicated-to-client function
When you call PlaySound in this context, UT does more work for you. In this scenario, the PlaySound is being called server-side. That does absolutely no good in a real game, since that sound would then not be heard by anyone. You might think it only has to be replicated, but if you'll remember, function replication is not multicast, so the sound would only be heard by the owner of the actor PlaySound is being called upon. Simulation doesn't help, since that would only happen if the sound was being called on the client. Simulation does not actually send anything over the network. So, UT performs some special magic instead. In Pawn, there is a ClientHearSound, whose definition is:
native simulated event ClientHearSound (
    actor Actor,
    int Id,
    sound S,
    vector SoundLocation,
    vector Parameters
);
This ClientHearSound is replicated from the server to the client, per the replication definition in Pawn. Remembering that it only goes to it's owner, this works fine, since calling Pawn.ClientHearSound(someactor...) on the server will cause that one pawn to hear the sound on the client, as if the sound came from someactor's direction. The special magic performed, is that UT effectively turns the call to PlaySound into a multicast function replication on ClientHearSound. When PlaySound is called, it iterates through all nearby players that should hear the sound, and replicates a call to ClientHearSound to each player. In this fashion, each player that should hear it, does hear it. And the original identity of the actor playing the sound is maintained through the first parameter to ClientHearSound.
This is actually quite the nifty behavior for PlaySound, as it causes the function to work the way it 'should,' in most cases. In the cases where it doesn't, you'll need to figure in it's dual nature, and figure out how to call it, (or call some other home-grown sound replication feature,) to make it work.
The other interesting behavior to talk about is that of PlayOwnedSound. The purpose of this function is to play the sound for everyone but the owner. This may seem strange at first, but there are a few uses for it. In UT, it used in most of the weapons. When a client fires a gun, they should get immediate feedback about the shot. That is why you see the weapon animations plya clientside, and hear the sounds clientside. However, the client cannot force sounds to be played elsewhere. What is done, is that the weapon plays a sound clientside immediately when the shot is fired. The client then tells the server it fired the gun, which then calls PlayOwnedSound with the sound, so that the sound can be heard by all the other clients. You wouldn't want the sound to be played on the player firing the gun, since they already played the sound. Hopefully that example is clear, but you can check the examples provided in UT's weapons if it does not satisfy you. One final note: when UT determines who is the owner, it only checks the actor itself (to see if it is the pawn or the playerpawn), and the immediate owner of the actor. It does not follow the hierarchy up like some other functions do.

ClientPlaySound and ClientReliablePlaySound

Here's a simple example, but still noteworthy nonetheless. ClientPlaySound is an unreliable function that plays a sound on the client. Calling PlayerPawn.ClientPlaySound(...) causes that player to play the sound locally on their machine. It is a location-less sound, and the sound is played as if it came from within their head, (as opposed to next to them, or in front of them, etc.) When called on the client, it is guaranteed to run, since no replication is involved, (it's a simulated function being called from a simulated function...) When it is called from the server, it is not guaranteed to reach the other end, however. What happens if you want to ensure that the sound is played? You call ClientReliablePlaySound, of course. This is a reliable function, which ensures that the sound reaches the client and is played. I'll just rip the whole ClientReliablePlaySound function, so you can see what is going on:
simulated function ClientReliablePlaySound(sound ASound, optional bool bInterrupt, optional bool bVolumeControl )
{
    ClientPlaySound(ASound, bInterrupt, bVolumeControl);
}
You can see that the reliable definition which is farther above in PlayerPawn ensures that ClientReliablePlaySound is run. Once that happens, the body of ClientReliablePlaySound is run on the client. There, it calls ClientPlaySound which ensures that the sound is played.

When Things Go Awry

What should you do when things go awry? There's two main techniques that I use, when trying to figure out what's going on. Technically, everything can be figured out with the first technique alone, but the second helps a lot in figuring out the applying technique.

Figure Out What's Going On

You need to isolate your problem. Know exactly what's happening. What stuff is being replicated, and what isn't. Then realize that those are only your assumptions, and that no matter what, you cannot be positive about them. With all the native stuff happening with replication, it's so easy to blame your problems on what's going on under the hood. In fact, after readinng this guide, you should be able to solve your problems yourself. I think I've covered just about every native replication aspect there is in this document. It's why it's so big. When I was having replication troubles, I remember that I wished there was documentation. I'd (and I'm sure others) would rather have too much than too little. Anyways, now that I've had access to the source, and have been able to know exactly what's been going on, I've been able to figure out why problems are happening in netplay, even ones that aren't my own. I say this only to point out that just knowing and understanding what's going on under the hood can make any problem solvable. You don't need extensivle trial and error to figure out where things are screwing up. Just thinking the problem through, and checking the unrealscript code, can provide you with the answer.
First, figure out what you believe is not replicating. Is it a function? A variable? What's going on exactly? Sometimes, because of intricate relationships in your code, you'll be unable to tell exactly what is 'missing' on the client. In that case, you'll need to use logging to figure out what's there and what's not. Logging is the second technique I mentioned. I'll discuss more on how to use it properly in debugging networking problems in a bit.

Check the Replication Statements

Anyways, once you figure out what's not being replicated, check the replication statement. 98% of the time, you can figure out why something is not replicating, by evaluating the replication statement yourself. I went through a great many replication statements in actor up above in the variable replication section. You might want to check there for some of the more common ones. But thinking about each part of the statement in turn will help you figure it out. Many times, stuff has a bNetInitial clause, which only happens the first time the actor is sent over the network when becoming relevant. This causes problems when your data isn't getting replicated midstream, or is at odd points, like when it goes out of and then comes back into relevancy. You can follow the function replication and simulation guidelines listed above to see if the function meets the criteria for being sent accross the network, or evaluated client-side.
Another programmer I've talked to had problems with his velocity not replicating when the grenades were thrown, but it was because they were only replicated on bNetInitial, and so that's why he never saw his velocity updates. Fiddling with the variables, he found that a RemoteRole of ROLE_DumbProxy seemed to work, as the grenades did seem to be moving. It may be hard to tell that's what is going on when you're on a LAN or even connecting to your own server, because of the small ping, and high bandwidth. But you can be sure that you're players playing over their modems will notice it. :) Remember the various properties of ROLE_DumbProxy, and ROLE_SimulatedProxy, and what side effects each causes, in terms of what is replicated. I've seen a few cases where that is the reason for their strange behavior. The problem with his approach was that he was getting the spoon-fed location updates from the server, and so in a real environment online, that would never work, since players cannot get location updates over the net and expect it to work right. In that case, the grenades should never be thrown from the inventory. ROLE_SimulatedProxy was a perfect fit for what he was trying to do, except for the fact that when he threw it, it was not bNetInitial. Instead, he just had to spawn a new actor, and give it the 'thrown' properties. That satisfied the criteria needed for the variable replication for ROLE_SimulatedProxy, and allowed the grenades to be thrown correctly, be simulated correctly, and it to all just work.

Logging is Your Friend

If that doesn't help you, try sticking logging statements in there. When you have two copies of UT running, a server and a client, two different logs are generated. One is a server log, and one is a client log. (doh :) If you aren't sure if a function is executing clientside, place a log in it. Then, check to see if that log appears in the clientside log. If it does, then the function is running on the client, and your strange behavior must be coming from elsewhere. If there is no log happening, then the function is not being executed. You may think it must be, because it is the only explanation for behavior you are seeing. But the logs do not lie. What is more often the case is that the function is being run on the server, and modifying variables, which are being replicated to the client, giving the appearance that the function ran on the client. As i talked about before, it can be easy to overlook this in LAN settings, but it will surely be found in real world conditions. I'll discuss how to test things in 'real-world' conditions in just a bit. Logging is your friend, and you should become quite familiar with it. Most Unreal Tournament programmers are already familiar with it, and if they've gotten bogged down in replication problems already, they're just about gunaranteed to have logged stuff in trying to figure things out. However, combine logging with a knowledge of what's actually going on, and you increase your chances of success manifold. I'll be covering a few 'case studies' of sorts at the end of the document. You'll be able to see exactly what's going on as each part is done, and hopefully the real-world examples of replication will make things clearer.

Testing Real-World Conditions

Testing a Mod in Netplay without a Network

It's always important to test your mod in netplay. Sometimes, it can be hard, when you don't have a bunch of people available to test with. However, there is nothing preventing you from running a server and a client on the same machine. This allows you to test netplay on a single machine.

Windows 9x

On Windows 9x, the UT client will consume 100% of the CPU by default. This is so that extraneous programs like ICQ, mirc, or whatever else you might have open do not steal CPU resources from your UT client, which should get full priority. This means that if you run a client and server on the same machine, the server will be starved of CPU cycles, and your UT client will experience extreme lag and packet loss. While you may want to simulate these at some point, this is not the way to go about doing it. Luckily, someone wrote a simple program that helps solve this dilemma of testing a UT server and client together. It was originally intended to solve this same problem for QuakeWorld servers, but it is perfectly applicable to our situation.
Let's disucss how to use it. First, download priority and extract it somewhere safe. I have mine in my UnrealTournament\System directory. Next start your server. Your best bet is to do this with the 'ucc server' commandlet. The general format for testing your mods should be:
ucc server mapname.unr?game=packagename.classname?packagename1.classname1,packagename2.classname2
Some example commandlines follow:
ucc server DM-Morbias][
ucc server DM-Morpheus?game=RocketArena.RocketArenaGame
ucc server CTF-Face?mutators=Botpack.InstaGibDM,Botpack.LowGrav
Next, you have to tell priority to give more priority to our UT server. You can read the readme associated with priority if you're interested in exactly what commandline parameters do what. But for our UT client/server testing purposes, just type the following in another window or command prompt:
ucc -title ucc
Now, our UT server will have the necessary CPU time it needs to run, even if a UT client is running. Now run the UT client, connecting to your local machine, with:
unrealtournament 127.0.0.1
Test your mod, and make sure it all works as you have planned. Of course, some things will require the use of more than one person to test, but at least you should be able to test and fix a large portion of your problems yourself, without requiring someone's valuable time, or requiring you to waste your own organizing a beta team and stuff.

Windows NT/2000

On Windows NT/2000, this is not a problem, since NT supports true multi-tasking, and so the use of priority.exe is not an issue. ////////////////////////////

Simulating Lag and PacketLoss

Testing multiplayer as described above only solves one problem. It helps you see if your code will execute in multiplayer correctly. However, the successful completion of that test does not mean that your mod will work in netplay. When testing netplay on your machine, your computer connects directly to itself, accross an incredibly fast and large connection. Testing on a LAN has the same 'problem', in that you will not be simulating the effect of people playing over modems on servers halfway around the world. Luckily, UT includes commandline options to help you simulate this type of behavior. They are: PktLoss, PktOrder, PktLag, and PktDup. These variables only affect data as it is being sent, so you will need to place them on the server and client to accomplish true lag. But first, if you check your UnrealTournament.ini, you'll notice references to SimPacketLoss and SimLatency. These worked once, in a land far, far away in a time long, long ago. They do absolutely nothing now, so you might as well remove them from your ini.
The true way to simulate lag is to use the commandline parameters when you start UT. We'll cover and document all of these variables here. To use these variables, you need to start UT like this: unrealtournament.exe server.ip.addr?PktLoss=4?PktLag=400. This will cause your UT client to experience this amount of lag when sending data to the server. Data sent from the server to the client till still travel at full speed, however. By the same token, you can also pass these variables to ucc with ucc server mapname.unr?PktLoss=10?PktLag=600. This will create a very 'bad' server with terrible conditions...probably too extreme even for real-life conditions. (If you play under 600 ping and 10% packetloss, then I feel bad for you. :) Let's get into the documentation of the individual variables. PktLoss will work all the time. The remaining three, PktOrder, PktLag, and PktDup are mutually exclusive, and if multiple options are passed on the commandline, the order just stated is the order they are checked. For example, if you pass PktLoss, PktLag, and PktOrder, then only PktOrder and PktLoss will be used. PktOrder has a higher priority than PktLag, and PktLoss always works.

PktLoss

The first, PktLoss. is set a percentage of packets sent. It determines the percentage of packets lost over the connection. Passing 10 will mean that 10% of the packets sent to the client will be lost to the bandwidth graveyard. Any packetloss usually will hurt a connection in real world connection, as many people complain about anything over 0% packetloss. So when testing, this value doesn't need to be that high, and probably should only range between 0 and 10. PktLoss set with: PktLoss=5

PktOrder

The next, PktOrder, determines whether packets will be sent out of order. This is simply a boolean flag, meaning that the only option for it is on/off, not a variable as in PktLoss. If this flag is set to on, it preclues the use of PktLag and PktDup, described below. PktOrder works like this: Every time a packet is going to be sent, it gets put at the end of a 'to-send' list. Then UT goes through the 'to-send' list, and sends half of the variables over the connection. While this is not truly random, it doesn't matter. It succeeds in it's goal in sending packets out of order, since they can be kept on the list for an indefinite length of time. PktOrder set with: PktOrder=1

PktLag

If you want to delay packets and simulate lag, then PktLag is the variable you want. Precluding the use of PktDup, and only working if PktOrder is not set, PktLag is set as a value of milliseconds. All packets being sent over the connection will be delayed by PktLag milliseconds. PktLag set with: PktLag=450

PktDup

If you want to simulate the effects of sending packets twice over the network, PktDup fits the bill. Only working if both PktOrder and PktLag are not set, PktDup is set as a percentage of packets that are duplicated. Every packet that is sent has a PktDup chance of being sent twice. All packets will be sent once. PktDup set with PktDup=20

Using the Variables

Now that you know how the variables work, here's a little lesson in how to use them. Remember that they only work for packets being sent. So if you set PktLag to 500 on the server, the client will experience 500 ms lag between what the server sent and what the client sees. Client packets sent to the server will go at their regular speed, however, which is usually around 40 ms each way on my machine. To truly test lag, you will need to use PktLag on both the client and the server. Ping, if you remember, is the time it takes for a packet to go round trip from client to server and back to client. To simulate a 500 ping, the best way would be to give a 250 PktLag on both the server and the client. All clients to connect to the server would then experience 250 ms additional lag, regardless of their local settings. The client would then add 250 ms additional lag itself through PktLag, resulting in a 500 ms effective ping.
Of the variables above, you will find yourself using PktLoss and PktLag most often. The others were more intended for Epic to test the results of it's own network code, and test it under extreme conditions that it could not duplicate. I doubt you will have need of PktDup or PktOrder unless you are unable to reproduce the player-reported problems about your mod being unresponsive or ineffective.

Conclusion

That's it, folks. Hopefully you now understand replication a lot more than you did before. Granted, it all may seem COMPLETELY overwhelming and confusing at first, and it is. But through application and testing of these principles, you will become more familiar with what is going on, and will better grasp network coding as time passes. You may need to read this document through a few times, before it all sinks in. If you find a section that is confusing even after you've read it through, send me an email at mongo@planetunreal.com. Don't expect me to help you out personally however, since I imagine I will probably get countless emails from new people that don't meet the basic assumptions I made and stated at the beginning of the document. It is always inevitable. Of course, those people probably haven't even read this far, so they'll be emailing me anyway, but I'm just letting you faithful readers know. :) I'm planning to read all your emails, and if they have good or valid suggestions for things to cover, or describe ambiguous or confusing aspects of my tutorial, then I'll make corrections and updates to this document in the future.
When something doesn't work, don't assume it's UT's native code in regards to replication. I believe I have successfully delineated all such hidden tricks in this document. The error has to be in your code, however much you don't like hearing that. Trust me, this is from experience. ;) Check your replication statements to make sure their logic is correct, and run through your code as both the server and the client, following the flow of logic to figure out what's going on. Make sure what you're expecting to be replicated or simulated IS ACTUALLY replicated or simulated, by following the checklists I've given in the document above. And as I stated before, LOG LOG LOG LOG. Fill your code chock-full of logs, to make sure that things are happening the way you want. After following all the guidelines, the only true test to make sure things are happening the way you expect is to put logs in, and see what is happening where. With all this in mind, I'm sure you will be successful in your future networking endeavors.
Good luck!
Mongo
Still to cover:

Special Networking Tricks (Case Studies)

Let's take a look at a few examples and problems that people have had, and an approach to solving them. Hopefully, this will help you solve your own problem, or at the very least, help you see how others have approached their problems, and fixed them.
thoroughly read through above sections on special properties of special stuff, realworld conditions, things go awry serverpackages packageflags native final functions are simulated automatically (?) state changes only seen for playerpawns, unless changed in simulated functions (then they cause problems for newly relevant actors) window stuff on client functions usually replicated before variables, cannot be sure Case Studies:
HUDMutators (everyone wants them :/ )
DrSiN's Window Replication Info
How to get custom pris: RAUT's PRI extra stuff (avoid spawnnotifies)
Laser-Guided-Ripper Tutorial get a better laserdot
UT's method for sending data to the server for playerpawns
How they did the GuidedWarhead in netplay
Weapon Replication/Networking overview (where?)
Other Neat Tricks
Faking replication of parent-variables that wouldn't normally replicate
Faking multicast replication with specially-owned objects by each player, that get functions called on them from a general function.
Use physics to your advantage Use of PHYS_Trailer for Halo, Shieldbelt
Use of Simulated ticks to accomplish clientside manual physics just a discussion, as complex code: Taliesin's code for inverse IK (hey, it's cool, too!)
Other ways of doing non-standard variable replication with functions, like Taliesin's code for seekers


The Mutator Class

Unreal Physics 101

by Pfoenix

Pfhoenix

mod exemplar

The purpose of this tutorial is to 'enlighten' those who are new to the Unreal Engine to how physics for objects work. This tutorial is not intended to be a "how to" for any particular problem, but instead strives to explain the physics types, how they operate, and how they are generally used.

Step 1 : Know your enumerations

The Actor class houses the all important enumeration (for those who aren't familiar with enumerations, I can at best refer you to Tim Sweeney's UnrealScript Language Reference document, an excellent source for general information on the UnrealScript language) : EPhysics, which is defined as such :

var(Movement) const enum EPhysics
{
PHYS_None,
PHYS_Walking,
PHYS_Falling,
PHYS_Swimming,
PHYS_Flying,
PHYS_Rotating,
PHYS_Projectile,
PHYS_Rolling,
PHYS_Interpolating,
PHYS_MovingBrush,
PHYS_Spider,
PHYS_Trailer
} Physics;

What this means is that there are 12 Physics 'types', though in reality, you really have 11 available to use (we'll get into why this is in a bit). Let's get down to business.

Step 2 : PHYS_Huh?

Let's get PHYS with it.

PHYS_None - as you might guess, this physics type does nothing. Nada. Zip, zilch, the calorie content of celery. With this physics set, your object will not do anything for you. It will sit there until you set it's velocity, and it will do exactly as you say with no fear of native code doing funny things to it.

PHYS_Walking - this physics type is not reserved, per se, but is useless to you unless you have a Pawn subclass, in which it is vital and you pretty much can't use anything else. For Pawns, this physics has a LOT of native code behavior - if the Pawn isn't on solid ground, native code will change the physics to PHYS_Falling automatically. If the Pawn is falling and hits ground (lands), native code will change the physics to PHYS_Walking automatically. This physics type is responsible for the movement and feeling of the players in Unreal / Unreal Tournament. The variables involved with this physics type are : GroundSpeed (the maximum speed the Pawn can move on the ground) and Acceleration (how quickly the Pawn accelerates to GroundSpeed).

PHYS_Falling - though this one was mentioned in conjunction with PHYS_Walking, don't be fooled - if nothing else, this is the most common physics type (other than projectile) among in-game objects. This physics type is responsible for objects being affected by gravity. Native code automatically adjusts the object's velocity in the direction and magnitude of the ZoneGravity vector in the zone that the object is in. Sure, this is a pretty simple thing to do on your own, but with native code doing the work for you, you're far better off (as well as having the benefit of taking the current zone properties into account). Be careful - if you have an object that, in script code, has it's velocity set specifically, even if it's set each Tick(), your object WILL (and this can't be emphasized enough, because it demonstrates the overpowering nature of native code) slowly move with the gravity of the zone it is in.

PHYS_Swimming - another Pawn related physics, though this one is not set by native code. Instead, this physics type is used to simulate swimming behavior and controls for the pawns, simulating bouyancy, among other things. Though it may feel a like flying, swimming physics also takes into account the zone's fluidfriction (all handled in native code), something flying does not.

PHYS_Flying - yet another Pawn related physics type. Flying tells the native code to do pretty much one thing - allow the player to move in any direction, unhindered by gravity. This means the player can move about freely, but still interacts (collides) normally with world objects and level geometry. The variables involved with this physics type are AirSpeed (the speed the Pawn can move through the air) and Acceleration (how quickly the Pawn accelerates to AirSpeed).

PHYS_Rotating - the name is pretty clear, though it's application isn't. Rotating is for objects that, that's right, rotate. This would include inventory items (like weapons on the ground) or level objects (like fans). The speed at with the object rotates is governed by a variable called RotationRate, a rotator.

PHYS_Projectile - this is the other most common physics type (other than falling) among in-game objects. This physics type is responsible for simple movements - straight paths of travel objects, like rockets or bullets. With this physics, the object will move according to it's set Velocity, ignoring gravity. Objects that use this physics type are very easy simulated and predicted (referring to network behavior model). Variables involved with this physics type are AirSpeed and Acceleration (same as flying).

PHYS_Rolling - the red headed step child of the physics types. This, in technical parlance, is seriously b0rk3d. Dead. Ceased to be. No more. An ex-physics type.

PHYS_Interpolating - a physics type that is largely used by native code. It is used when moving Movers between keypoints as well as players between set interpolation points. This physics type is not something you are likely to ever need, unless you are putting together a map fly-through or complex mover for a map.

PHYS_MovingBrush - for Movers specifically, this physics type is responsible for the movement of elevators, platforms, doors.. i.e. any brush that moves around in a map, this physics (powered by native code) makes it work.

PHYS_Spider - if your first impression is to think of things walking on walls and ceilings, you'd be partially right. This physics was intended to allow objects to treat any level geometry surface as the 'ground'. This physics type is rarely used, and even more rarely experimented with.

PHYS_Trailer - a fairly common physics type. Trailer does one very nice thing - tells the object that has the physics type of Trailer to stay with (location wise) the object that owns it. Trailer is the easiest way to make sure that one object is always at the location (or a nearby offset) of it's owner, and because it's handled by native code, you won't see lag in locations in net games. Variables involved with this physics type are bTrailerSameRotation (tells the Trailer'd object's rotation to always be the same as the owner), bTrailerPrePivot (tells the native code to offset the location of the Trailer'd object from the Owner object by a vector, PrePivot), and PrePivot (a vector which is the the offset measured in world coordinates and is treated as an absolute vector offset, not relational to the Owner's rotation).

Step 3 : Physics in Action - Collisions

Now that you have the physics you want, it's important to understand how the Unreal engine detects collisions between objects. Level geometry is referred to as BSP geometry, or Binary Space Partition geometry. Without getting into too much detail, it's sufficed to say that collision with level geometry happens on a per polygon hit detection. Everything else (i.e. all Actor classes) works off of what's called a Collision Cylinder. In the Actor class, you have several key variables :

CollisionHeight - the height, measured in Unreal units, of the collision cylinder as measured from the middle of the actor to the top. This means that in reality, the collision cylinder is really 2 * CollisionHeight - the object's location is CollisionHeight off the ground (or the bottom of the cylinder is CollisionHeight below Location.Z) and the top of the cylinder is at Location.Z + CollisionHeight.

CollisionRadius - the radius of the cylinder

bCollideWorld - whether or not the object will collide with level geometry

bCollideActors - whether or not the object will collide with other actor objects

bBlockActors - whether or not the object will stop a moving Actor when they collide

bBlockPlayers - whether or not the object will stop a moving player when they collide

It is important to note that the collision cylinder does not rotate with the object - it is static and stays perpendicularly upright at all times (greatly simplifies collision detection calculations). Now, when a collision occurs, several functions might get called, depending on variables set.

HitWall(vector HitNormal, Actor HitWall) - if bCollideWorld is on, this event function gets called by the engine, letting the object know the normal to the collision plane between the level polygon and the object (the HitNormal points towards the object), as well as an Actor reference, which would let you know a couple things - if HitWall == Level, you've hit normal level geometry, if it's a Mover, then you've hit a mover.
Landed(vector HitNormal) - if the object physics is PHYS_Falling, this event function gets called by the engine when the object lands on level geometry while falling. HitNormal is the surface normal of the level geometry landed on.

Bump(Actor Other) - if bBlockActors or bBlockPlayers is on, this event function gets called for both objects. This event function gets called by the engine only once - at the initial time of the collision.

Touch(Actor Other) - if bCollideActors is on, this event function gets called by the engine for both objects. This event function gets called every Tick() that the collision still occurs. When collision happens the first time, there is an array of actors, called Touching[], which is a list of other actors touching this one. Other is put into the array if it isn't already there by native code. Touching[] is defined as const, meaning you cannot manually change any values of the array within UScript.

UnTouch(Actor Other) - if bCollideActors is on, this event function gets called by the engine for both objects. This event function is called when colliding objects are no longer colliding (as soon as the collision isn't occuring any more, this even function is called, but only once).

When it comes to event functions being called, be forewarned. Sometimes, the engine will not call both Touch() and Bump() - if both objects are bBlockPlayers, Bump() will be called, Touch() won't. If one object is bCollideActors and the other is bBlockActors, the object being bumped (the bCollideActors object) will get a Bump() event while the other will simply get a Touch() call.

Now you should at least have a good handle on the basics of physics and collision with the Unreal engine. There is a lot you can do with the rather simple tools given. Enjoy what you've learned here and experiment!


Unreal Audio Subsystem

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Level Designers, UnrealScript Programmers, C++ Programmers.
Last Updated: 01/25/02

Audio-related classes

UAudioSubsystem is the abstract base class of the sound subsystem.

The actual sound subsystem is implemented in a subclass of UAudioSubsystem. The reference implementation is UGalaxyAudioSubsystem, which supports the Galaxy music and sound system. However, UAudioSubsystem is general enough that it can be ported to other sound systems fairly easily.

USound contains a sound sample with the following characteristics:

  • .WAV format.
  • 8-bit or 16-bit format.
  • Monaural.
  • Either one-shot or looped.

UMusic contains a digital music file with the following characteristics:

  • 32 or fewer channels maximum (16 or fewer recommended).
  • .MOD, .STM, .S3M, .IT format.

UnrealScript interface

PlaySound (Actor class): plays a simple, non-looping sound effect emmanating from the actor. Use this for all normal game sound effects. You can specify the following parameters:

  • Sound: A sound effect; should be a one-shot (non-looping) sound.
  • Slot: One of the eight "slots" to play the sound in. This enables you to prevent more than one sound from playing on a particular slot. For example, when an enemy is shot several times in rapid succession, you want the successive sound effects to cut each other off, rather than hearing a chorous of simultaneous, overlapping screams.
  • Volume: Sound volume multiplier. 1.0 means "normal volume", 0.5 means "half volume", 2.0 means "double volume", etc.
  • bNoOverride: Whether this sound effect should override another sound playing on the same slot, or be ignored.
  • Radius: Radius of the sound in world units, defaults to 4096.0.
  • Pitch: Pitch multiplier. 1.0 means "normal pitch", 0.5 means "half pitch".

ClientHearSound (PlayerPawn class): called when a particular PlayerPawn actor hears a sound effect. This is how sounds are sent to clients in a network game. You may call this function directly (in a particular PlayerPawn) to have only that one player hear a sound.

ClientSetMusic (PlayerPawn class): Sets the music for a particular player.

UnrealEd music tips

In UnrealEd's music and sound browsers, you can listen to music and sound effects by double-clicking on them, or with the Play/Stop buttons. You can hear the level's ambient sounds while editing by clicking on the realtime button in the 3d view (it looks like a joystick icon).

Any actor in Unreal can emit an ambient sound. The properties to check out are AmbientSound, SoundRadius, SoundVolume, and SoundPitch. When you turn on UnrealEd's "Show Actor Radii" option in a 2d view, you can see the ambient sound radii as blue circles.

In Options/Level, you can set the default music, music section, and cd track for the level.

MusicEvent actors work similarly to SpecialEvent actors, in that they let you cause music changes in response to any event, such as the player touching a trigger, killing a monster, etc. In multiplayer games, MusicEvent actors only cause a music change in the player which caused the event, not all players in the game. MusicEvents have a "Song" variable which you can set to "None" if you want to use the song you set for the level in Options/Level.

3D positioning

A sound is positioned in 3d space, positioned at the Location of the actor who played the sound effect or ambient sound.

As the actor that played the sound moves around, the actor's sound is repositioned. The affects the following properties:

  • Distance attenuation.
  • Doppler shifting.
  • Stereo panning (if UseStereo is enabled).
  • Dolby Surround Sound positioning (if UseSurround is enabled).

Doppler shifting is based on the emitting actor's Velocity. Note that it is possible for actors to move around directly with SetLocation or MoveActor without having a valid Velocity, thereby causing no doppler shifting.

Dolby SurroundSound software encoding requires a Dolby decoder and four speakers, but it works on all stereo sound cards. It simply pans sound effects and ambient environment sounds between the four Dolby channels (center, rear, left, and right).

Sound slots

Each actor in the world has eight "sound slots", so it can play up to 8 simultaneous (overlapping) sound effects.

When an actor plays a sound in a slot where an old sound is already playing, the old sound can either be cut off and overridden, or the new sound can be ignored (see the bNoOverride parameter in PlaySound).

Sound slot zero (SLOT_None) is special: it indicates that a sound should not interrupt any other sounds. For sound effects like rapid-fire gunshots, use SLOT_None to allow multiple instances of the sound to play simultaneously.

In Unreal, there is a hard limit to the number of sound effects which may be playing simultaneously. This limit is set in the Unreal.ini file, and can vary from 16 to 32. During gameplay, the sound engine prioritizes each sound effect according to its volume and its distance from the listener, and culls the least important sounds. High-volume sounds override low-volume sounds, and sounds near the listener override sounds far away from the listener.

Sounds

Sound effects can be either 8-bit or 16-bit, and can be sampled at any reasonable rate (4kHz-44kHz). What rate and bit depth to use is entirely a quality vs. memory usage tradeoff. In general, use the lowest bit depth and sampling rate which gives you acceptable sound quality.

For best sound quality, make sure your sound effects are not clipped, i.e. sampled at so high a volume that the tops or bottoms of their waveforms are truncated.

Ambient sounds

Each actor in the level can have one ambient sound effect, which is specified in its AmbientSound property. This should refer to a sound effect which loops. If a non-looping sound effect is used as an AmbientSound, it will not play properly (it will only play once).

Persistence and correctness

Sounds have a radius. They diminish linearly according to distance and are culled when too far away to hear. Culling distance is a linear function of the sound's volume.

Ambient sounds persist across loads and saves.

Regular sound effects do not persist across loads and saves. A regular sound effect can only be heard by players (local and network) who can hear it when it begins playing. For example, if you have a 10-second sound effect and you start playing it in a room, then five seconds later a far-away player teleports into the room 5 seconds later, he will not hear the sound at all.

Looping sound effects

To create a looping sound effect in a .wav file, you need a sound editing program like SoundForge (http://www.sfoundry.com) which supports looping sound effects. In Sound Forge, follow these instructions:

  1. Run SoundForge.
  2. Load your .wav file (either 8-bit or 16-bit).
  3. Bring up the "Special/Edit Sample..." dialog.
  4. Click on the "Sustaining" choice (as opposed to "One shot").
  5. Select "File/Save As...".
  6. Make sure that the "Save Sampler Information in file" option is checked.
  7. Click on the "Save button".

Limitations

Software-mixed sound:

  • 3D sounds are only stereo panned, but not fully spatialized (i.e. phase shifted and bandpass filtered based on sound absorption in the ear as a function of position).
  • The sound system is limited to a maximum of 64 channels of music and sound. By default, 16 sound effects channels are allocated, leaving 48 for music. You can change this from the Unreal.ini file.
  • Each playing sound effect, ambient sound, and music channel uses CPU time. Therefore, we recommend keeping the number of sound effects audible to the player fairly low, and keeping music channel usage "lean and mean".

Hardware-mixed sound:

  • 3D sounds are spatialized by whatever the hardware supports. For example, Aureal pans it, phase shifts it, and applies a complex convolution and bandcap filter to model positional modulation of the sound by the head and ears.
  • The sound system is limited to X channels of hardware mixed sound (where X depends on the kind of hardware, and can be from 6 to 64 for existing sound hardware). Any sounds for which hardware acceleration is unavailable are emulated in software using the software mixer, and thus may sound different (less spacey) than the same sound played on hardware.

Dynamic music

Each level has a default song and CD track which is played throughout the level. You can specify the song in UnrealEd in "Options/Level" in the "Audio" tab.

Music can be transitioned dynamically via a SpecialEvent object hooked up to a trigger or any other event source.

Music is not zone based, because that would become annoying when backtracking through maps and in network play.

Music is tracked per player so it can be used equally well in single player and network play.

Zone-based echo and reverb

The audio subsystem includes a six-tap sound reverberation filter which enables you to customize the echo and reverb effects on a per-zone basis (there can be up to 64 zones in a level, so you can have quite a bit of variety in the audio postprocessing within a level). When you add a ZoneInfo actor into a zone, you can set the following properties:

  • bool bReverbZone: True to enable reverberation effects in the zone; False to disable them.
  • [this is outdated, but the quick version is: the other properties are 6 reverb tap delays and gains]

You can experiment with reverberation filters quickly by going to Options/Level, setting the reverb effects for the entire level, then double-clicking on sound effect names in the sound browser.

Music formats

Unreal supports two major kinds of music:

  • CD audio. You can compose your game's sound track, record it on CD, and specify in-level music by CD track. Advantages of CD audio include highest possible music quality, no CPU overhead, and giving composers the freedom to create music however they want. The major drawback is that you can't do dynamic music very well since switching between CD tracks isn't instantaneous, and you can't distribute it via the Internet.
  • Digitally mixed music (.mod, .s3m, .it, etc). These are special music formats which include digitally recorded instruments as well as sequencing data. Advantages: Easy to distribute on the Internet, and more amicable to dynamic music. Disadvantages: somewhat CPU intensive to mix (3%-5% of CPU time), lower sound quality than CD.

Windows platform implementation notes

We only support 16-bit sound output. We tested 8-bit sound output and the quality was unacceptable low: when you mix 64 channels of sound into an 8-bit output stream, you effectively get 2-bit sound effects. 2-bit sound effects are Not Good.

The sound system supports both the legacy WinMM sound support, and DirectSound. DirectSound generally achieves the lowest latency, while WinMM works on Win95 machines which don't have DirectSound, and WinNT.

The sound code makes heavy use of MMX to improve mixing quality and speed. You get about a 2X performance and quality boost on Pentium processors with MMX technology.

On non-MMX machines, the sound code makes some quality/speed tradeoffs by limiting sound effects to having only 64 volume levels. You can hear this limitation by setting up an ambient sound effect with a high radius in an otherwise quiet area: the discrete steps between volume levels are quite audible.


Unreal C

Unreal C++ Objects

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Licensee programmers who have access to the Unreal C++ source.
WORK IN PROGRESS -- This document is far from complete.
Last Updated: 01/25/02

Where do I look for info?

  • UnObjBas.h: FObjectManager (the global object manager, GObj) definition. UObject definition. Helper macros.
  • UnCorObj.h: Look here for definitions of some of Unreal's simpler object classes.

When do I need to write a C++ Serialize function?

C++ UObject-derived classes for which you write a script (a .uc file) automatically are able to serialize themselves completely. In this case, serialization simply involves the engine automatically going through all of the variables defined in the script (bytes, floats, object pointers, etc) and serializing them. Since the script defines the layout of variables, you don't need to write any serialization code because the engine already knows what to serialize.

If you don't have a .uc script for your class (meaning it's purely written and implemented in C++), you need to write a serialize function that overrides UObject::Serialize, to serialize the new variables you've added. Here' is a code fragment example.

class UWhatever : public UObject
{
    DECLARE_CLASS(UWhatever,UObject);

    // New variables.
    INT A;
    FLOAT B;
    FString C;

// UObject interface.
void Serialize( FArchive& Ar )
{
    UObject::Serialize( Ar ); // Must route to superclass to serialize the superclass variables and stuff.
    Ar << A << B << C; // Serialize these variables.
    if( Ar.IsLoading() )
    {
        // If you have any special cleanup code you want to execute when loading, stick it here (optional).
    }
}

How does saving a pointer to an object causes that object to be saved?

When you are saving a package (UPackage* Pkg) and during serialization to the archive (FArchive& Ar) you save a pointer to an object (UObject* Obj) by passing it to the archive (Ar << Obj), Unreal automatically saves two things: (1) the reference to the other object, so that it is automatically linked up with the proper object when you load it, and (2) the other object, *IF* it's in the package that is being saved. If the other object resides in another package, it only saves the reference to it as an "import".

Unreal serialization works like MFC serialization and Java serialization in that you save one base object (for example the ULevel) and the framework automatically serializes the entire graph of objects that are reachable to the base object. This is the standard object-oriented way of loading and saving stuff.

However, Unreal (unlike MFC and Java) has the concept of packages which enables saving only the objects in the graph which reside in a certain package. This approach combines the benefits of the traditional OOP serialization patter (being able to automatically save complex interrelated objects) with the benefits of Windows DLL style dynamic linking (being able to develop stuff as a bunch of modules, which publically export certain objects, and import other objects) which enables object-code modularization.

What resides in the Unreal binary package files?

An Unreal package file on disk corresponds to one top-level package (i.e. UnrealI.u corresponds to the UnrealI package, MyLevel.unr corresponds to a level named MyLevel).

From a high level point of view, an Unreal binary package file contains four distinct things:

  1. The name table (a table of C++ FName's) which maps unique text strings to indices.
  2. The import table, which lists all of the external objects, in other packages, that this package depends on. These are just described by name, just as the symbol table in a .DLL file lists functions imported from other DLL's.
  3. The export table, which lists all of the objects that reside in the package file, and tells where to find it within the current package file.
  4. The export data, which contains a bunch of raw serialized data for each exported object.

How do I write an external utility to read and write Unreal binary files?

The data in Unreal binary files describes highly complex interrelated objects whose characteristics are totally dependent on Unreal's object framework, so trying to read and write them outside of the engine is not a fruitful activity. When you need to get data in and out of the engine, the best way to do that is through plug-ins, either written in C++ (for editor tools, data importers, or performance critical plug-in code) or UnrealScript (for game stuff; UnrealScript doesn't execute in the editor).

The main categories of plug-ins of interest are:

  • Import tools for importing data from other file formats (graphics, models, etc) into the engine. For this, you'll want to write a new factory object (see the UFactory class, and UnEdFact.cpp for many examples). A factory is an object responsible for importing data from one or more files and constructing one or more UObject's from that data.
  • Export tools. Code for these can go into the game or editor. The typical approach is to traverse whatever Unreal objects you want and use fopen, fclose, fread, fprintf, etc. to write it out to a file.
  • New kinds of non-actor Unreal objects -- new algorithmic texture types, etc. The best approach for extending Unreal objects or creating new kinds of UObject derived classes is C++ subclassing. Here you take a base class like UObject, UTexture, etc. and you create a child class, and write whatever functions are appropriate for that class including, if your object is savable, a serialization function.
  • New kinds of actors -- the best approach is UnrealScript subclassing. You write a new .uc file. In this case, the engine takes care of all the details of serialization for you as long as you write a valid script.

Are package names hardcoded into files?

No! If you have a package named "MyPackage" and you save it to the file "NewName.u", the next time you load it, it will be called "NewName". Alternatively, when you load a package you can optionally specify its name (which may differ from the filename). Within a binary package file, there are absolutely no hardcoded references to the package's name.

How do "packages within packages" work?

Explain.

How can I best manage importing complex game data into new classes of C++ objects?

We've found that the easiest way to manage complex game objects (like your conversations) is to describe them in one or more UnrealScript classes residing in .uc files, add in a few new "#exec" commands in UnEdSrv.cpp to import your custom format data, and build those .uc files into a .u binary files using "unreal -make". For example, look at the humongous UnrealI.u file which contains a ton of scripts, sounds, textures, and meshes imported from a huge number of source files. With this approach:

1. You can create your basic content in text files (or other industry standard files) or your own simple, proprietary format.
2. You can change your UObject-derived object formats without completely breaking your content -- you just do another "unreal -make". This is important. I've gone through over 300 breaks of the .u file format!

What you will probably want to do is create one package containing ALL of your DConEvents, to avoid tying them to individual level.s One easy way to do this is:

1. Create a new directory (for example) \unreal\con, and \unreal\con\classes.
2. Create a script \unreal\con\AllConEvents.uc that looks something like this:

//=============================================================================
// AllConEvents.
//=============================================================================
class AllConEvents expands Object
    abstract;

// A variable to contain references to the sounds we're importing.
var object Refs[10];

// Import the sounds. Note: #exec commands are only executed when you rebuild from the
// command line using "unreal -make". See Packages.htm for more info.
#exec AUDIO IMPORT FILE="Sounds\Skaarj\amb1sk.WAV" NAME="amb1sk" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\Skaarj\syl07.WAV" NAME="syl07sk" GROUP="Skaarj"
#exec AUDIO IMPORT FILE="Sounds\Skaarj\syl09.WAV" NAME="syl09sk" GROUP="Skaarj"

// Force this class to reference the sounds we imported, so that they'll be saved
// in this package file.
defaultproperties
{
    Refs(0)=amb1sk
    Refs(1)=skl07
    Refs(2)=syl09
}

3. Add "Con" to the "EditPackages" section of Unreal.ini so it will be properly rebuild when you do an "unreal -make". (It searches thru all directories listed in the EditPackages section and rebuilds packages whose .u files have been deleted).

The above example assumes I want to stick a bunch of sound files in the package (stored as .wav's on disk, brought into Unreal as USound objects). If you want to import a bunch of conversations, you need to write a new "#exec" handler in UnEdSrv.cpp to import your data from your custom file format into some UObject derived class like DConversation.

How are objects unique identified and created within a package?

Within a package (which defines a namespace):

  • If you don't specify a name, Unreal creates a guaranteed unique name for you:
    • The guaranteed unique name is generated by appending a unique number onto the class name, for example Pawn23.
  • If you specify a name, and the name is unique, a new object is created.
  • If you specify a name, and the name matches that of another object of the SAME class, the other object is replace with the new one.
    • The old object's C++ destructor (and its UObject Destroy() function) are called.
    • The new object is constructed at the same memory location as the one it replaces.
    • Therefore any pointers to the replaced object are still valid, since they still point to the same class object.
    • The new object's C++ constructor is called.
  • If you specify a name, and the name matches that of another object of a DIFFERENT class.
    • You get a critical error message because this situation cannot be resolved safely.

End


Unreal Console Commands

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Advanced Users, Server Administrators, Programmers.
Last Updated: 01/25/02

Command Line Parameters

  • -alladmin: Enable all players administrative access to the server.
  • -conflicts: Show objects of different classes whose names conflict.
  • -editor: Runs Unreal for editing.
  • -firstrun: Re-asks the "First Run" questions in Unreal.
  • -log: Runs with the log window initially visible.
  • -nobind: Don't treat UnrealScript/C++ binding errors as critical, for rebuilding scripts and avoiding the chicken-and-egg binding problem.
  • -noddraw: Disables DirectDraw support.
  • -nodsound: Disables DirectSound support.
  • -nogc: Disables garbage collection.
  • -nohard: Disables 3d hardware support.
  • -nok6: Disable AMD K6-3D support.
  • -nolog: Don't show log window.
  • -nommx: Disables MMX support.
  • -noreplace: Don't automatically replace textures, sounds, and music if they are not found.
  • -nosound: Disables sound.
  • -nowarn: Disables warning message boxes on the screen.
  • -profile: When C++ is compiled with DO_SLOW_GUARD=1, generates an UnrealScript function profile using the timings in the most recently played level only.
  • -make: Rebuilds all .u files from their source .uc files.
  • -make -h: Rebuilds all .u files from their source .uc files and generate a C++ header for each package.
  • -safe: Runs Unreal in "safe mode", avoiding loading any device drivers which could crash if there are hardware/driver problems.
  • -server: Runs as a dedicated server.
  • -showdep: Causes script compiler to log dependency information when recompiling scripts.
  • -silent: Run silently, with no log window, and no display of error messages. Critical errors just cause the engine to exit silently.
  • -strict: Treat all script warnings as critical errors; useful for tracking down the call stack when debugging scripts.
  • INI=inifilename: Sets the .ini file to use for configuration, normally Unreal.ini.
  • LOG=logfilename: Uses the specified log file instead of Unreal.log. Useful when running multiple copies on the same machine.
  • MULTIHOME=12.34.56.78: Sets the "home" ip address (in numerical format) for Unreal of a machine with multiple network cards.
  • PORT=num: Sets the UDP port number for the Internet server.
  • READINI=inifilename: Sets the .ini file for reading only (not for writing); overrides the INI= option.

C++ Console Commands (Only works on the local machine)

  • ADMIN: Sends a console command to the server you're connected to. You must be an administrator in order to use this.
  • BRIGHTNESS: Cycle through 10 screen brightness values.
  • CHAT: Brings up a prompt to type chat text.
  • CANCEL: Cancels an "open" command in progress that is trying to connect to a network server.
  • CDTRACK num: Play the specified CD track.
  • CONSOLE FULL: Make the console fullscreen.
  • CONSOLE HIDE: Hide the console.
  • CONSOLE SHOW: Show the console.
  • CPUSPEED=#: Identify your CPU speed, useful for machines which don't autodetect their speed properly. For example, CPUSPEED=266.
  • DEBUG CRASH: Test crashing the game by appError.
  • DEBUG EATMEM: Test allocating memory until it fills up.
  • DEBUG GPF: Test a general protection fault.
  • DEBUG RECURSE: Test crash by infinite recursion.
  • DUMPCACHE: Display the contents of the memory cache GCache.
  • DUMPNATIVES: Display a list of unused native function ids.
  • EDITACTOR CLASS=classname: During game play, edits the properties of the nearest actor belonging to that class. Cool for debugging.
  • ENDFULLSCREEN: Go back to playing in a window.
  • EXEC filename: Execute the console commands in the filename, default is in the System directory.
  • EXIT: Exit the program.
  • FLUSH: Flush all caches. Regenerates all lighting, 3d hardware textures, etc.
  • FLY: Fly around (instead of walking). See WALK.
  • FOV angle: Set the field of view, for example "FOV 90" for 90 degrees.
  • GHOST: Fly around and go through walls (see WALK).
  • HIDEACTORS: Hide actors during game play.
  • JUMPTO x y z: In UnrealEd, move the viewport to a certain X,Y,Z location, useful in conjunction with tester reports generated with the REPORT command.
  • LOADGAME num: Load a game in position 0-9.
  • MARK: Mark all objects that are in memory (for garbage collection debugging in conjunction with MARKCHECK).
  • MARKCHECK: Display a list of all unmarked objects that are in memory (for garbage collection debugging in conjunction with MARK).
  • MEM: List memory usage; only works when Unreal is compiled with the memory-tracking option (it's usually not).
  • MEMSTAT: Show Windows overall memory statistics.
  • MUSICORDER num: Change to a certain track in the song (0=ambient, 1=action, 2=suspense).
  • OBJ CLASSES: Prints a list of all loaded classes.
  • OBJ DEPENDENCIES PACKAGE=pkgname EXCLUDE1=otherpackage EXCLUDE2=otherpackage...: !!
  • OBJ GARBAGE: Collect and purge garbage ("garbage" means objects which are no longer in use).
  • OBJ HASH: Show object hashing statistics.
  • OBJ LINKERS: Show a list of active linkers (each linker is responsible for loading objects from a package file).
  • OBJ LIST CLASS=objectclass INSIDE=insideclass: List all objects belonging to the class and residing inside the specified object. If the class isn't specified, lists ALL objects. If the inside object isn't specified, shows all objects. Gives a summary of memory usage. This is very useful during game play for figuring out how much memory is being used. In UnrealEd, this statistic isn't useful because a huge amount of extra stuff is loaded which might not be used by your map.
  • OBJ REFS CLASS=objectclass NAME=objectname: Show a list of objects which reference the object you specify. When trimming memory usage, this is useful for figuring out why some object is being loaded.
  • OPEN url: Opens a local map (i.e. "unreal.unr") or an Internet server (i.e. "200.0.1.16" or "unreal.epicgames.com").
  • PREFERENCES: Displays the preferences in a window.
  • REPORT: Copies a report of the current gameplay situation to the clipboard. You can then paste the resulting text into an email program, Notepad, etc. Extremely useful for beta testers, because it dumps the player's X,Y,Z location, the difficulty level, etc.
  • RMODE: Set the rendering mode. 0-9.
  • SAVEGAME num: Save the game in a specified position, 0-9.
  • SHOT: Take a screenshot and save it in the System directory with a consecutive name like Shot0001.bmp.
  • SHOWACTORS: Shows actors during gameplay.
  • SOCKETS: In network play, shows a list of network sockets (UNetConnection's) in use.
  • STAT ACTOR: Shows various statistics.
  • STAT CACHE
  • STAT CLIP
  • STAT FILTER
  • STAT FPS
  • STAT GAME
  • STAT GLOBAL
  • STAT HARDWARE
  • STAT ILLUM
  • STAT LIGHT
  • STAT MESH
  • STAT POLYC
  • STAT POLYV
  • STAT REJECT
  • STAT OCCLUSION
  • STAT SOFT
  • STAT SPAN
  • STAT ZONE
  • TOGGLEFULLSCREEN: Toggles fullscreen mode on and off.
  • TYPE: Types text on the console.
  • URL urlname: In network play, parses a URL and displays its components.
  • VIEWUP: Sizes the view up.
  • VIEWDOWN: Sizes the view down.
  • WALK: Walk around normally (see FLY, GHOST).

UnrealScript console commands (Can be used by remote administrators)

  • ADDBOTS <number>: Adds more bots to the game.
  • ALLAMMO: Gives you all the ammo for your current weapons.
  • GOD: Makes you invincible.
  • INVISIBLE: Makes you invisible.
  • KILLALL <class name>: Kills all actors of a certain class, for example "KILLALL UNREALI.BRUTE".
  • KILLPAWNS: Kills all monsters.
  • PLAYERSONLY: Pauses all non-player actors in the game. Cool for debugging scripts, taking screenshots.
  • SAY <message string>: Broadcast a message to other players in the game.
  • SLOMO <number>: Sets the game speed, 1.0 is normal.
  • SETNAME <newname>: Change your name (works in network play too).
  • SETTEAM <newname>: Change your team (works in network play only when the rules allow).
  • SUMMON <class name>: Spawns an actor of the specified class (for example, SUMMON UNREALI.BRUTE) in front of the player.
  • SWITCHCOOPLEVEL <new level URL>: Causes the server (or local machine, in a single-player game) to switch to a new level with coop-style weapon carrying between levels.
  • SWITCHLEVEL <new level URL>: Causes the server (or local machine, in a single-player game) to switch to a new level.

Console configuration commands

  • GET <classname> <variablename>

Gets a configurable class parameter. <classname> may be a partial classname, such as "playerpawn", or a qualified classname such as "engine.playerpawn". The class must be loaded in memory, otherwise GET returns an empty string. <variablename> must be the name of a variable that is designated as configurable (either in UnrealScript using the "config" keyword or in C++ using CPF_Config). This returns the value of the configured variable, converted to a string. The value returned by GET reflects the class's default value (for scripted classes, this is the default value that was set for the class using its property sheet). At any time, zero or more instances of objects belonging to <classname> may be in memory, and may have modified values of <variablename>, and they don't affect the value returned by "GET".

  • SET <classname> <variablename> <value>

Sets the default value of a class's variable. If the class is designated as configurable (using the "config" keyword in UnrealScript or CLASS_Config in C++), and so is the variable, this function updates the Unreal.ini file to reflect the new default value. If any instances of objects belonging to <classname> are in memory, all of those objects are updated. When an object's config variables are updated, they are notified as follows:

  1. The object's PreEditChange() function is called, basically saying "Get ready to be modified!"
  2. The object's configurable variables are updated with the newly configured values.
  3. The object's PostEditChange() function is called, saying "You've been modified, so validate and update yourself".

This procedure enables objects to validate their configurable properties and update themselves. For example, the audio subsystem's PostEditChange() function clamps the sound volume to a safe range of 0.0 - 1.0 (because the SET command enables users to set it to ridiculous values) and then updates the actual volume of the sound effects that are playing.

Unreal Key Bindings

In the Unreal key bindings (under Advanced Options / Advanced / Raw Key Bindings), you can associate console commands and other special input commands with key presses and releases. In the text box next to a key name, you can type in one or more console commands, separated by the "|" character. For example, to bind the "S" key to the "Jump" alias, type this:

    Jump

That causes the "Jump" alias to be executed when th user presses the "S" key. For another example, if you want to bind a chat message to a key, use this:

    Say "Come get some!"

In addition, you can bind multiple actions to a keypress like this, to make the "S" key both jump and say a message.

    Jump | Say "Come get some!"

You can also bind an action to the release of a key by using the OnRelease keyword. For example, you can make the "S" key fire when it's released:

    OnRelease Fire

Or you can make the key jump when pressed, and fire when released:

    Jump | OnRelease Fire

Keys can be bound to any of the following kinds of things:

  • Any console command in the above lists.
  • Any key alias (explained below).
  • Any special input command.

"Special input command" refers to console commands which only make sense in conjunction with the press or release of a key, or the movement of the mouse or joystick along an axis. The special input commands are:

  • BUTTON <UnrealScript boolean variable name>, for example "BUTTON bFire": Maps a button to an UnrealScript variable stored in the Pawn class or any subclass. This tells the input system to automatically set the variable to True when the key is held down, and False when it's not pressed. For example, the Pawn script looks at bFire to tell whether the fire button is being held. The setting of bFire is not some hardcoded behavior of the engine, rather it is propagated into UnrealScript code by the input system, as a result of binding a key to "BUTTON bFire".
  • TOGGLE <UnrealScript boolean variable name>, for example "TOGGLE bLook": Like the BUTTON command, but simply tells the input system to toggle the boolean variable's value when the key is pressed.
  • AXIS <UnrealScript floating point variable name> <SPEED=some number>, for example "Axis aStrafe Speed=-300.0". Maps an analog input axis movement to an UnrealScript variable, scaling it by some factor. The current axis keys listed in the Advanced Options menu are: MouseX, MouseY, MouseW (Intellimouse wheel), JoyX, JoyY, JoyZ, JoyR (joystick rudder), JoyU, JoyV (joystick alternate axis for example the Panther XL trackball). Supported PlayerPawn axes are aBaseX, aBaseY (base movements which are translated to rotating, strafing, looking, and forward movement based on context), aMouseX, aMouseY, aForward, aTurn, aStrafe, aUp (not used), aLookUp, aExtra0-aExtra4 (not used). To see how the game code processes movement, see the PlayerPawn class's PlayerInput and PlayerTick functions.

In addition to the Advance Options menu, you can also bind keys from the console using the following command:

    SET INPUT <keyname> <binding>

For example:

    SET INPUT X Fire
    SET INPUT Enter Fire

Unreal Key Aliases

Key aliases are listed in Advanced Options / Advanced / Input Aliases. Aliases provide a convenient way to map one word (for example, "Jump") to a complex series of console commands that carry out a particular action. For example, the "Fire" alias is defined as: "Fire | Button bFire". This has the effect of calling the UnrealScript "PlayerPawn.Fire" function (aliases are not recursive), and then causing the input button bJump to be set to True as long as the key is held.


Unreal Tournament Console Commands

Jack Porter
Epic Games, Inc.
http://www.epicgames.com/
Based on the Unreal 1 console commands document.

Audience: Advanced Users, Server Administrators, Programmers.
Last Updated: 01/25/02

Introduction

This is a list of console commands and command line options, most of which are valid for the current version of the UT demo. The upcoming version of the demo will add a few of the new ones. The cheat codes will be changed for the full version of UT.

UnrealTournament.exe Command Line Parameters

-changevideo | Bring up the video card selection menu
-conflicts | Show objects of different classes whose names conflict.
-log | Runs with the log window initially visible.
-noddraw | Disables DirectDraw support.
-nodsound | Disables DirectSound support.
-nogc | Disables garbage collection.
-nohard | Disables 3d hardware support.
-nok6 | Disable AMD K6-3D support.
-nolog | Don't show log window.
-nokni | Disables KNI (Pentium III) support
-nommx | Disables MMX support.
-nosound | Disables sound.
-nowarn | Disables warning message boxes on the screen.
-profile | When C++ is compiled with DO_SLOW_GUARD=1, generates an UnrealScript function profile using the timings in the most recently played level only.
-safe | Runs Unreal in "safe mode", avoiding loading any device drivers which could crash if there are hardware/driver problems.
-server | Runs as a dedicated server. See ucc server
-silent | Run silently, with no log window, and no display of error messages. Critical errors just cause the engine to exit silently.
INI=inifilename | Specify the .ini file to use for configuration. Normally UnrealTournament.ini.
USERINI=userinifilename | Specify the .ini file to use for user-specific configuration. Normally User.ini
LOG=logfilename | Uses the specified log file instead of UnrealTournament.log. Useful when running multiple copies on the same machine.
MULTIHOME=12.34.56.78 | Sets the "home" ip address (in numerical format) which Unreal Tournament will bind to, for a machine with multiple IP addresses.
PORT=num | Sets the UDP port number for the Internet server.
READINI=inifilename | Sets the .ini file for reading only (not for writing); overrides the INI= option.

Ucc.exe Command Line Parameters

UCC.exe is the command line UnrealTournament launcher. It launches a number of "commandlets". ucc help will give you a list of available commandlets.

Ucc make

-h | Rebuilds all .u files from their source .uc files and generate a C++ header for each package.
-nobind | Don't treat UnrealScript/C++ binding errors as critical, for rebuilding scripts and avoiding the chicken-and-egg binding problem.
-strict | Treat all script warnings as critical errors; useful for tracking down the call stack when debugging scripts.

Ucc server

Usage: ucc server URL [parameters]
Most of the parameters valid for unrealtournament.exe are valid for ucc server.
The URL parameter is usually just a map name, but can include a number of options:

  • ?alladmin - give all players administration access
  • ?game= -specify the game class
  • ?mutator= - specify a list of mutator classes (comma separated)

UnrealScript Console Commands

General console commands

MENUCMD <menu> <menuitem> | Perform an UnrealTournament menu item. For example, MENUCMD 1 0 brings up the Unreal Tournament server browser
SAY <message string> | Broadcast a message to other players in the game.
SETNAME <newname> | Change your name (works in network play too).
SUICIDE | Commit Suicide
TEAMSAY <message string> | Broadcast a message to your teammates.

Practice session console commands/cheats. Most of these will change.

ADDBOTS <number> | Adds more bots to the game.
ALLAMMO | Gives you all the ammo for your current weapons.
FLY | Fly around (instead of walking). See WALK.
GHOST | Fly around and go through walls (see WALK).
GOD | Makes you invincible.
KILLALL <class name> | Kills all actors of a certain class, for example "KILLALL WARHEADLAUNCHER".
KILLPAWNS | Kills all bots
PLAYERSONLY | Pauses all non-player actors in the game. Cool for debugging scripts, taking screenshots.
SLOMO <number> | Sets the game speed, 1.0 is normal.
SUMMON <class name> | Spawns an actor of the specified class (for example, SUMMON BOTPACK.WARHEADLAUNCHER) in front of the player.
VIEWCLASS <class name> | Cycle through actors of this class, viewing from their locaton. eg VIEWCLASS BOT
WALK | Walk around normally (see FLY, GHOST).

Admin console commands. Some of the above practice session cheats are available in network play when you're logged in as an administrator.

ADMIN <command> | Perform a console command on the server's console
ADMIN SERVERTRAVEL <new level URL> | Causes the server to switch to a new level.
ADMIN SET UWeb.Webserver bEnabled True | Enable the remote admin webserver (requires a level change to take effect)
ADMIN SET UWeb.Webserver bEnabled False | Disable the remote admin webserver (requires a level change to take effect)
ADMINLOGIN password | Login as an administrator
ADMINLOGOUT | Drop administrator access
KICK <playername> | Kick a player
KICKBAN <playername> | Kick a player and ban his/her IP. You'll need to edit your ini file or use the WWW remote admin to unban their IP

C++ Console Commands

These only work on the local machine.

BRIGHTNESS | Cycle through 10 screen brightness values.
CANCEL | Cancels an "open" command in progress that is trying to connect to a network server.
CDTRACK num | Play the specified CD track.
CPUSPEED=# | Identify your CPU speed, useful for machines which don't autodetect their speed properly. For example, CPUSPEED=266.
DEMOPLAY <filename>
[?noframecap]
[?timebased]
[?3rdperson] 		Play a recorded demo. noframecap plays the demo back as fast as possible. This option is assumed if timedemo 1 is enabled. timebased gives a smoother playback if the playback machine is significantly slower than the recording machine. 3rdperson lets you fly around a first person demo as a spectator. eg demoplay mydemo?3rdperson?timebased
DEMOREC <filename> | Record a demo to <filename>
DISCONNECT | Disconnect from the current server
ENDFULLSCREEN | Go back to playing in a window.
EXEC filename | Execute the console commands in the filename, default is in the System directory.
EXIT | Exit the game..
FLUSH | Flush all caches. Regenerates all lighting, 3d hardware textures, etc. Can be useful to clear texture corruption due to 3D hardware driver bugs
FOV angle | Set the field of view, for example "FOV 90" for 90 degrees.
GETCOLORDEPTHS | Get a list of color depths supported by your 3D hardware
GETCURRENTCOLORDEPTH | Get the current color depth (16 or 32)
GETCURRENTRES | Get the current resolution
GETRES | Get a list of available resolutions
HIDEACTORS | Hide actors during game play.
JUMPTO x y z | In UnrealEd, move the viewport to a certain X,Y,Z location, useful in conjunction with tester reports generated with the REPORT command.
MUSICORDER num | Change to a certain track in the song (0=ambient, 1=action, 2=suspense).
NETSPEED number | Change your desired network data rate. Use 2600 for modem, 5000 for ISDN, 20000 for Cable/ADSL/LAN
OPEN url | Opens a local map (eg "dm-turbine.unr") or an Internet server (eg "200.0.1.16" or "unreal.epicgames.com").
s_occfactor | A3D 2.0 occlusion factor
s_maxnodedist | A3D 2.0 maximum node distance
s_reflect 0 or 1 | A3D 2.0 reflections
s_occlude 0 or 1 | A3D 2.0 occlusions
s_wavetracing 0 or 1 | A3D 2.0 Wavetracing
s_refgain | A3D 2.0 reflection gain
s_refdelay | A3D 2.0 reflection delay
s_maxpoly | A3D 2.0 maximum number of polygons
s_maxreflectpoly | A3D 2.0 maximum number of reflection polygons
s_polysmall | A3D 2.0 smallest polygon size
s_polylarge | A3D 2.0 large polygon size
s_a3dsources | A3D 2.0 Sources
SETRES WxHxD | Set the resolution and color depth. eg SetRes 800x600x32
SERVERTRAVEL url | Change levels from the UnrealTournament Server console window.
STOPDEMO | Stop recording or playing back a demo.
PREFERENCES | Displays the Advanced Options window.
RECONNECT | Reconnect to the current/previous server
SHOT | Take a screenshot and save it in the System directory with a consecutive name like Shot0001.bmp.
TOGGLEFULLSCREEN | Toggles fullscreen mode on and off.
TYPE | Types text on the console.

Also see the Mesh LOD document for Mesh LOD console commands.

Statistics

STAT ACTOR | Shows various statistics.
STAT CACHE
STAT CLIP
STAT FILTER
STAT FPS | Show frame time in milliseconds
STAT GAME
STAT GLOBAL | Shows useful performance timings in milliseconds
STAT HARDWARE
STAT ILLUM
STAT LIGHT
STAT MESH
STAT NET | Show network performance statistics including ping, packet loss, bytes/second
STAT POLYC
STAT POLYV
STAT REJECT
STAT OCCLUSION
STAT SOFT
STAT SPAN
STAT ZONE

Debugging

DEBUG CRASH | Test crashing the game by appError.
DEBUG EATMEM | Test allocating memory until it fills up.
DEBUG GPF | Test a general protection fault.
DEBUG RECURSE | Test crash by infinite recursion.
DUMPCACHE | Display the contents of the memory cache GCache.
DUMPNATIVES | Display a list of unused native function ids.
EDITACTOR CLASS=classname | During game play, edits the properties of the nearest actor belonging to that class. Cool for debugging.
GET <classname> <variable> | Gets the default value for a variable in a class
MARK | Mark all objects that are in memory (for garbage collection debugging in conjunction with MARKCHECK).
MARKCHECK | Display a list of all unmarked objects that are in memory (for garbage collection debugging in conjunction with MARK).
MEM | List memory usage; only works when Unreal is compiled with the memory-tracking option (it's usually not).
MEMSTAT | Show Windows overall memory statistics.
OBJ CLASSES | Prints a list of all loaded classes.
OBJ DEPENDENCIES PACKAGE=pkgname EXCLUDE1=otherpackage EXCLUDE2=otherpackage... | Show package dependencies
OBJ GARBAGE | Collect and purge garbage ("garbage" means objects which are no longer in use).
OBJ HASH | Show object hashing statistics.
OBJ LINKERS | Show a list of active linkers (each linker is responsible for loading objects from a package file).
OBJ LIST CLASS=objectclass INSIDE=insideclass | List all objects belonging to the class and residing inside the specified object. If the class isn't specified, lists ALL objects. If the inside object isn't specified, shows all objects. Gives a summary of memory usage. This is very useful during game play for figuring out how much memory is being used. In UnrealEd, this statistic isn't useful because a huge amount of extra stuff is loaded which might not be used by your map.
OBJ REFS CLASS=objectclass NAME=objectname | Show a list of objects which reference the object you specify. When trimming memory usage, this is useful for figuring out why some object is being loaded.
REPORT | Copies a report of the current gameplay situation to the clipboard. You can then paste the resulting text into an email program, Notepad, etc. Extremely useful for beta testers, because it dumps the player's X,Y,Z location, the difficulty level, etc.
RMODE | Set the rendering mode. 0-9.
SET <class> <variable> <value> | Sets the specified property of the specified class with the specified value
SHOWACTORS | Shows actors during gameplay.
SOCKETS | In network play, shows a list of network sockets (UNetConnection's) in use.
URL urlname | In network play, parses a URL and displays its components.

Unreal Tournament Key Bindings

In the Unreal Tournament key bindings (type PREFERENCES to bring up Advanced Options / Advanced / Raw Key Bindings), you can associate console commands and other special input commands with key presses and releases. In the text box next to a key name, you can type in one or more console commands, separated by the "|" character. For example, to bind the "S" key to the "Jump" alias, type this:

    Jump

That causes the "Jump" alias to be executed when th user presses the "S" key. For another example, if you want to bind a chat message to a key, use this:

    Say "Come get some!"

In addition, you can bind multiple actions to a keypress like this, to make the "S" key both jump and say a message.

    Jump | Say "Come get some!"

You can also bind an action to the release of a key by using the OnRelease keyword. For example, you can make the "S" key fire when it's released:

    OnRelease Fire

Or you can make the key jump when pressed, and fire when released:

    Jump | OnRelease Fire

Keys can be bound to any of the following kinds of things:

  • Any console command in the above lists.
  • Any key alias (explained below).
  • Any special input command.

"Special input command" refers to console commands which only make sense in conjunction with the press or release of a key, or the movement of the mouse or joystick along an axis. The special input commands are:

  • BUTTON <UnrealScript boolean variable name>, for example "BUTTON bFire": Maps a button to an UnrealScript variable stored in the Pawn class or any subclass. This tells the input system to automatically set the variable to True when the key is held down, and False when it's not pressed. For example, the Pawn script looks at bFire to tell whether the fire button is being held. The setting of bFire is not some hardcoded behavior of the engine, rather it is propagated into UnrealScript code by the input system, as a result of binding a key to "BUTTON bFire".
  • TOGGLE <UnrealScript boolean variable name>, for example "TOGGLE bLook": Like the BUTTON command, but simply tells the input system to toggle the boolean variable's value when the key is pressed.
  • AXIS <UnrealScript floating point variable name> <SPEED=some number>, for example "Axis aStrafe Speed=-300.0". Maps an analog input axis movement to an UnrealScript variable, scaling it by some factor. The current axis keys listed in the Advanced Options menu are: MouseX, MouseY, MouseW (Intellimouse wheel), JoyX, JoyY, JoyZ, JoyR (joystick rudder), JoyU, JoyV (joystick alternate axis for example the Panther XL trackball). Supported PlayerPawn axes are aBaseX, aBaseY (base movements which are translated to rotating, strafing, looking, and forward movement based on context), aMouseX, aMouseY, aForward, aTurn, aStrafe, aUp (not used), aLookUp, aExtra0-aExtra4 (not used). To see how the game code processes movement, see the PlayerPawn class's PlayerInput and PlayerTick functions.

In addition to the Advance Options menu, you can also bind keys from the console using the following command:

    SET INPUT <keyname> <binding>

For example:

    SET INPUT X Fire
    SET INPUT Enter Fire

Unreal Tournament Key Aliases

Key aliases are listed in Advanced Options / Advanced / Input Aliases. Aliases provide a convenient way to map one word (for example, "Jump") to a complex series of console commands that carry out a particular action. For example, the "Fire" alias is defined as: "Fire | Button bFire". This has the effect of calling the UnrealScript "PlayerPawn.Fire" function (aliases are not recursive), and then causing the input button bJump to be set to True as long as the key is held.


Unreal Engine Redistribution

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Unreal Technology Licensees
Last Updated: 01/25/02

Who redistributes

Only authorized licensees who have signed an Unreal engine licensing agreement with Epic MegaGames may redistribute the Unreal binaries.

What Unreal compontents to redistribute

All of the engine .exe's and .dll's required to run the game.
All of the plug-in DLL's that are applicable, such as GlideDrv.dll for 3dfx Glide support, etc.

Changes licensees need to make

General changes:

  • Rename your game executable to something other than Unreal.exe (of course), for example WheelOfTime.exe.
  • Rename the config file to match your executable name, for example rename Unreal.ini to WheelOfTime.ini. The engine automatically uses the .ini file whose name matches the executable file, so you need not modify any code to reflect the new .ini name.
  • Make whatever changes are needed to your game .ini file and Default.ini to reflect your game settings. Unreal.ini should (upon clean installation) always be an exact copy of Default.ini.
  • Change the map file extension. Our extension is .unr. Your extension should be something else, so that if a user installs multiple Unreal engine titles on his machine, the file associations don't get screwed up, i.e. when the user double clicks on an .unr file, Unreal should run it; a .wot file should be run by Wheel of Time.

Changes to the Unreal.ini file:

  • Change Registry.* to reflect your product.
  • Change UdpBeacon.Port to a new Udp port number.
  • Change UdpBeacon.Product to a single word that identifies your product.
  • Change URL.Protocol to reflect your game. This is used in URL's such as unreal://gameserver.com/ or wheeloftime://somesite.com/.
  • Change URL.ProtocolDescription.
  • Change URL.MapExt to your map file extension (ours is "unr").
  • Change URL.SaveExt to your savegame file extension (ours is "usa").
  • Change URL.Port to a unique TCP/IP port for LAN and internet gameplay.
  • Change URL.LocalMap to the map you want players to start on (ours is Unreal.unr).

GameSpy Configuration

In the initial Klingon Honor Guard patch there are KHG servers showing up underneath "Unreal" in GameSpy. Here are the steps Unreal licensees can take to setup their own entries in GameSpy:

First, contact David Wright (CRT) at GameSpy. His email address is wrightd@stanford.edu and his ICQ UIN is 2652565. Tell him you are interested in getting GameSpy support setup for your game. You will need to get a "Unique Game String" and a "Secret Key" from him. The Unique Game String is a string that uniquely identifies your game...for Unreal the string is "unreal". KHG's string might be "klingon". The Secret Key is a key that is used to generate validation for your game. Encrypted validation is necessary to ensure hackers can't flood the master server with fake game entries.

Once you have these two elements make the following code changes:

  1. On line 50 of IpServer.UdpServerUplink change:
    HeartbeatMessage = "\\heartbeat\\"$Query.Port$"\\gamename\\unreal";
    to the same thing with your Unique Game String in the place of unreal. For example:
    HeartbeatMessage = "\\heartbeat\\"$Query.Port$"\\gamename\\klingon";
  2. On line 367 of IpServer.UdpServerUplink change the GenerateSecretKey function to generate the secret key for your own game. It is highly suggested that you DO NOT release a version of your game with the secret key blatantly listed as a string constant. If you do so, the string will be visible in the string table. Alternatively, write a simple, but obfuscated function to generate the secret key. (See my GenerateSecretKey function as an example of a simple way of creating said key.) (Line numbers will vary, obviously. These are line numbers as of the 220 release of Unreal, which you guys don't have yet... *shrug*) Once you have done these changes you will be ready for GameSpy. Additional information on the GameSpy protocol can be obtained from GameSpy proper. This way each licensee will be able to have their own entries in GameSpy (less confusing to players and beneficial in many other ways...)

Installation issues

Install all of the Unreal engine binaries to your application's directory. Our default directory is Unreal, and our setup calls for installing the executables and DLL's in the System subdirectory, which defaults to \Unreal\System. Unreal is designed so that it does not need to install any shared DLL's into the user's \Windows or \Windows\System directory, because doing so tends to create hellish version-management problems. Unreal's only external dependency that doesn't ship with all versions of Win95/WinNT is the Visual C++ runtime (MSVCRT.DLL), which we always install to the \Unreal\System directory to prevent potential version conflicts with other versions of the Visual C++ runtime in the user's \Windows\System directory.

Do not install any Unreal binaries into the user's \Windows or \Windows\System directories, as these files are frequently modified and not intended to be shared between applications.

We use InstallShield for our installation. See InstallShield Corporation for info about it. It's the least bad installation tool we've found.

End


Unreal Localization Support

Tim Sweeney
Epic MegaGames, Inc.
tim@epicgames.com
http://www.epicgames.com/

Audience: UnrealScript Programmers, C++ Programmers, Translators.
Last Updated: 01/25/02

External Localization Links

  • Microsoft Global Development Page
  • To Find a Translator
  • Visual C++ Unicode documentation (requires Visual C++)
  • Windows Code Pages List (requires Visual C++)
  • Unicode Test Page
  • Worldwide Web Consortium: International Resources

Overview of Unreal localization support

The design goals for Unreal's translatability are:

  • Make Unreal-technology based games easily translatable, where translations to UNICODE languages (basically, all worldwide languages that are significant to the PC and consumer electronics markets) require no changes to source code or binary data files.
  • Build localization support into the engine at a fundamental level so that all the translation work can be done by a translator person without taking programmer or level designer time.
  • Make translations modular, so that translations can be installed after a game has been purchased.
  • Keep translations robust, so that when updates/patches to a game are released, they don't need retranslated; and if a particular piece of text hasn't been translated, be able to fall back gracefully on the international english text.
  • Make the translation support portable, which means that Windows resources (which are great for translating pure Windows apps) are problematic.

The approach we chose is to place localized text in .ini style files which correspond to Unreal package files. Translation capability is available in UnrealScript and C++ in three key areas:

  • Native script support: default string properties of actor (and object) classes can be defined using the "localized" keyword in UnrealScript (or CPF_Localized in C++). These default properties contain the international english text as specified by the programmer or level designer. However, text in the current language's .ini files overrides text in the .u files, so translations can be performed purely by creating a new .ini file, without modifying any code.
  • In C++ and UnrealScript, there are Localize() functions which take an arbitrary key name and return its corresponding localized text. This is intended mainly for C++ code where there is no convenient UObject containing default properties in which to place the translatable string.
  • The translation .ini files contain a [LocalizedNames] section which enables mapping UnrealScript names (C++ FName's) to localized text. This is used in areas of the engine which are based on FName's internally but must use a localized representation of those FName's for display and user interaction purposes. For example, the Preferences windows are based on direct editing of named UnrealScript properties (like SoundVolume) which must be translated into other languages, and which also may benefit from being translated into more human-readable English, for example "Sound Volume Level".

Authoring UnrealScript code for translatability

Put all readable text into string instance variables, and use the "localized" keyword to designate them as localized, and use the "localized" keyword when declaring the class. For example:

This code will be a bitch to translate because it will require messing with the code:

class OuchSayer expands Trigger;
function Trigger( Pawn A, Actor B )
{
    A.Message( "Ouch, you touched me!" );
}

This code will be easy to translate because it can be done in an .ini file by a non-programmer:

class OuchSayer expands Trigger localized;
var() localized string[64] Msg;
function Trigger( Pawn A, Actor B )
{
    A.Message( Msg );
}
defaultproperties
{
    Msg="Ouch, you touched me!"
}

The other advantage of this approach is that it makes it easy for a writer to go through and clean up the English text in a game. This has been beneficial in Unreal development, because we have a lot of level designers and programmers writing game text which needed reworking due to stylistic inconsistencies.

Character set

Unreal is designed to use the 16-bit UNICODE character set. The standard Unreal fonts include only the first page of UNICODE language characters, but our built-in TrueType font importer enbales you to import (with optional antialiasing) any Unicode TrueType font, i.e. for piecing together Unreal fonts that support the roman languages, Japanese, and Korean.

Localized file extensions

Each language has a characteristic file extension, which Unreal uses to try to find the localized text for a given package file. For example, we define the following extensions:

  • Filename.int: International English text.
  • Filename.fr: French text.
  • Filename.de: German text.
  • Filename.esp: Spanish text.
  • Filename.itt: Italian text.

When Unreal loads a package file (such as an .unr level file, or a .u class file), it searches for localized text in the following places. For example, when loading MyLevel.unr:

  • If using a language other than English, it looks in that language's localized file, such as MyLevel.fr for French.
  • If that file was not found, it looks in the international English version, MyLevel.int.
  • Otherwise, the text stored in the raw package file is used.

Preparing level text for translation

Lots of game text is stored within .unr level files, for example the text messages stored with Counters, Triggers, and TranslatorEvent actors. The intent is that level designers will write the first-pass version of this text in English, and then the text will be localized (or the English version cleaned up) by a translator or writer, who edits the .ini files and never modifies the .unr level file itself.

Not modifying binary data files (such as .unr level files, and .u class files) is an important concept, because many aspects of Unreal, including network play, rely on the exact binary contents of these data files. If translations were performed by having someone actually modify the .unr levels, or .uc scripts (thus affecting the .u binary files), it would be impossible for French or German people to play on American Unreal servers, etc.

UnrealEd supports a special console command analyze an Unreal binary file (such as an .unr or .u file) and generate an .ini style text file containing the international English version of the text. For example, to process UnrealI.u, type on the console:

    dumpint UnrealI.u

And that generates the file UnrealI.int, the international text for the package. That file can then be given to translators, who rename it to their appropriate language's extension (such as UnrealI.fr or UnrealI.de) and translate all of the text within.

Hardcoded C++ translation support

CORE_API const char* Localize( const char* Section, const char* Key, const char* Package=GPackage );
  • Looks in the localization file corresponding to Package (i.e. Engine.int for the Engine package, using international English) and returns the localized string for Key, found in the Value section. If Package isn't specified, it defaults to the current package being compiled.
CORE_API const char* LocalizeError( const char* Key, const char* Package=GPackage );
CORE_API const char* LocalizeProgress( const char* Key, const char* Package=GPackage );
CORE_API const char* LocalizeQuery( const char* Key, const char* Package=GPackage );
CORE_API const char* LocalizeGeneral( const char* Key, const char* Package=GPackage );
  • These functions work like Localize but they look in a the section corresponding to their function name instead of taking Section as a string. For example, LocalizeError looks in the "Error" section.

Hardcoded UnrealScript translation support

intrinsic function string[192] Localize( name KeyName, name SectionName, name PackageName );
  • This puppy does the same thing as the C++ Localize function.

Debugging translations

When a C++ or UnrealScript localization function is called for which no corresponding localized .ini file entry is found, the returned string is displayed as <?Package.Section.Key?>, and an entry is written out to the log to record the missing translation. This is a non-critical error. Because this is easy to screw up, I recommend coverage testing all lines of code which lookup localized text.

Non-technical information for translators

You can edit .int files with a text editor like Notepad. A typical .int file will contain a lot of data that looks like this:

[Errors]
FileOpen=Error opening file
FileNotFound=Can't find file '%s'
FileClose=Error closing file

[Progress]
Saving=Saving file %s...
Closing=Closing

Bold text indicates the text to be translated. For clarity, these .int files contain three kinds of data:

  • Section headings, such as [Errors] and [Progress]. These are used internally by Unreal. Do not translate these!
  • Key names such as FileOpen= and FileClose=. These are used internally by Unreal to identify the text. Do not translate these.
  • Translatable text such as Error opening file and Saving file %s.... This text always immediately follows the "=" sign. Translate this.

So, for example, the result, translated file above might look like:

[Errors]
FileOpen=Fehleröffnung Datei
FileNotFound=Kann nicht Datei %s finden
FileClose=Schließende Datei des Fehlers

[Progress]
Saving=Einsparungdatei %s...
Closing=Schließen

There are several important points to keep in mind:

  • Be sure to test all translated text thoroughly in the game to make sure it's complete and it fits in the space available. Some areas that contain text, such as the menus, have a limited amount of space and the translated text will overflow if it's too large.
  • When you see symbols like %s or %i in the text, leave them and be sure not to move them around. These characters are used by Unreal to designate where numbers, and other text appear. For example, changing "Loading item %i from file %s" to "Loading file %s, item %i" will cause Unreal to crash when it displays the text. Unreal typically formats a message like "Loading item %i from file %s" into something like "Loading item 10 from file Unreal.unr"
  • The standard Unreal fonts should contain all of the ANSI characters necessary for translation into standard ANSI languages.

Limitations

  • Unreal's text printing support is currently limited to left-to-right. Support for other orientations, or bidirectional text (i.e. for Arabic or Hebrew) is not provided, but could be pieced together without too much pain.

End


Unreal Networking Architecture

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Advanced UnrealScript Programmers, C++ Programmers.
Last Updated: 01/25/02

Note: References to Unreal's C++ code are only relevant to Unreal licensees who have access to the Unreal source.

History

Multiplayer gaming is about shared reality: that all of the players feel they are in the same world, seeing from differing viewpoints the same events transpiring within that world. As multiplayer gaming has evolved from the little 2-player modem games that characterized Doom, into the large, persistent, more free-form interactions of games like Quake 2, Unreal, and Ultima Online, the technologies behind the shared reality have evolved tremendously.

In the beginning, there were peer-to-peer games like Doom and Duke Nukem. In these games, each machine in the game was an equal. Each exactly synchronized its input and timing with the others, and each machine carried out the same exact game logic on exactly the same inputs. In conjunction with completely deterministic (i.e. fixed-rate, non-random) game logic, all players in the machine perceived the same reality. The advantage of this approach was simplicity. The disadvantages were:

  • Lack of persistence. All of the players had to start the game together, and new players couldn't come and go as they pleased.
  • Lack of player scalability: Because of the lock-step nature of the networking architecture, the coordination overhead and chance of network-induced failure increases linearly with the number of players.
  • Lack of frame rate scalability. All of the players had to run at the same internal frame rate, making it difficult to support a wide variety of machine speeds.

Next came the monolithic client-server architecture, pioneered by Quake, and later used by Ultima Online. Here, one machine was designated "server", and was responsible for making all of the gameplay decisions. The other machines were "clients", and they were regarded as dumb rendering terminals, which sent their keystrokes to the server, and received a list of objects to render. This advancement enabled large-scale Internet gaming, as game servers started springing up all over the Internet. The client-server architecture was later extended by QuakeWorld and Quake 2, which moved additional simulation and prediction logic to the client side, in order to increase visible detail while lowering bandwidth usage. Here, the client receives not only a list of objects to render, but also information about their trajectories, so the client can make rudimentary predictions about object motion. In addition, a lock-step prediction protocol was introduced in order to eliminate perceived latency in client movement. Still, there were some disadvantages to this approach:

  • Lack of open-endedness: When users and licensees create new types of objects (weapons, player controls, etc), glue logic must be authored to specify the simulation and prediction aspects of those new objects.
  • Difficulties of the prediction model: In this model, the network code and the game code are separate modules, yet each must both be fully aware of the implementation of the other, in order to keep the game state reasonably synchronized. A strong coupling between (ideally) separate modules is undesirable because it makes extensibility difficult.

Unreal introduces into multiplayer gaming a new approach termed the generalized client-server model. In this model, the server is still authoritative over the evolution of the game state. However, the client actually maintains an accurate subset of the game state locally, and can predict the game flow by executing the same game code as the server, on approximately the same data, thus minimizing the amount of data that must be exchanged between the two machines. Further, the "game state" is self-described by an extensible, object-oriented scripting language which fully decouples the game logic from the network code. The network code is generalized in such a way that it can coordinate any game which can be described by the language. This achieves a goal of object-orientation which increases extensibility, the concept that the behavior of an object should be fully described by that object, without introducing dependencies on other pieces of code which are hard-wired to know about the internal implementation of that object.

Basic Concepts

Goal

The goal here is to define Unreal's networking architecture in a fairly rigorous manner, because there is a fair amount of complexity involved that is easy to misinterpret if not defined exactly.

Basic Terminology

We define our basic terminology precisely:

  • A variable is an association between a fixed name and a modifiable value. Examples of variables include integers such as X=123, floating point numbers such as Y=3.14, strings such as Team="Rangers", and vectors such as V=(1.5,2.5,-0.5).
  • An object is a self-contained data structure consisting of a fixed set of variables.
  • An actor is an object capable of independently moving around in a level and interacting with other actors in that level.
  • A level is an object which contains a set of actors.
  • A tick is an operation that updates the entire game state given that a variable amount of time called DeltaTime has passed.
  • The game state of a level refers to the complete set of all actors that exist in that level and the current values of all of their variables at a time when a tick operation is not currently in progress.
  • A client is a running instance of Unreal.exe which maintains an approximate subset of the game state suitable for approximately simulating the events that occur in the world, and for rendering an approximate view of the world for a player.
  • A server is a running instance of Unreal.exe which is responsible for ticking a single level and communicating the game state authoritatively to all of the clients.

The Update Loop

All of the above concepts are well-understood with the possible exception of the tick and game state. So, these will be described in more detail. First of all, here is a simple description of Unreal's update loop:

  1. If I am a server, communicate the current game state to all of my clients.
  2. If I am a client, send my requested movement to the server, receive new game state information from the server, render my current approximate view of the world to the screen.
  3. Perform a tick operation to update the game state, given that a variable amount of time DeltaTime has passed since the previous tick.

A tick operation involves updating all of the actors in the level, carrying out their physics, informing them of interesting game events that have occurred, and executing any necessary script code. Unlike many past games such as Doom and Quake, all of the physics and update code in Unreal is designed to handle a variable amount of time passing. For example, Doom's movement physics looks like "Position += PositionIncrment" while Unreal's looks like "Position += Velocity * DeltaTime". This enables greater frame rate scalability.

While a tick operation is in progress, the game state is being continually modified by the code which executes. The game state can change in exactly three ways:

  • A variable in an actor can be modified.
  • An actor can be created.
  • An actor can be destroyed.

The Server Is The Man

From the above, the server's game state is completely and concisely defined by the set of all variables of all actors within a level. Because the server is authoritative about the gameplay flow, the server's game state can always be regarded as the one true game state. The version of the game state on client machines should always be regarded as an approximation subject to many different kinds of deviations from the server's game state. Actors that exist on the client machine should be considered proxies because they are a temporary, approximate representation of an object rather than the object itself.

Bandwidth Limitation

If network bandwidth were unlimited, the network code would be very simple: at the end of each tick, the server could just send each client the complete and exact game state so that the client always renders the exact view of the game as is occurring on the server. However, the Internet reality is that 28.8K modems have only perhaps 1% of the bandwidth necessary to communicate complete and exact updates. While consumers' Internet connections will become faster in the future, bandwidth is growing at a rate far lower than Moore's law which defines the rate of improvement in games and graphics. Therefore, there is not now and never will be sufficient bandwidth for complete game-state updates.

So, the main goal of the network code is to enable the server to communicate a reasonable approximation of the game state to the clients so that the clients can render an interactive view of the world which is as close to shared reality as is reasonable given bandwidth limitations.

Replication

Unreal views the general problem of "coordinating a reasonable approximation of a shared reality between the server and clients" as a problem of "replication". That is, a problem of determining a set of data and commands that flow between the client and server in order to achieve that approximate shared reality.

The Relevant Set of Actors

Definition

An Unreal level can be huge, and at any time a player can only see a small fraction of the actors in that level. Most of the other actors in the level aren't visible, aren't audible, and have no significant effect on the player. The set of actors that a server deems are visible to or capable of affecting a client are deemed the relevant set of actors for that client. A significant bandwidth optimization in Unreal's network code is that the server only tells clients about actors in that client's relevant set.

Unreal applies the following rules in determining the relevant set of actors for a player.

  1. The actor belongs to the ZoneInfo class, then it is relevant.
  2. If the actor has static=true or bNoDelete=true, then it is relevant.
  3. If the actor is owned by the player (Owner==Player), then it is relevant.
  4. If the actor is a Weapon and is owned by a visible actor, then it is relevant.
  5. If the actor is hidden (bHidden=true) and it doesn't collide (bBlockPlayers=false) and it doesn't have an ambient sound (AmbientSound==None) then the actor is not relevant.
  6. If the actor is visible according to a line-of-sight check between the actor's Location and the player's Location, then it is relevant.
  7. If the actor was visible less than 2 to 10 seconds ago (the exact number varies because of some performance optimizations), then it is relevant.

These rules are designed to give a good approximation of the set of actors which really can affect a player. Of course, it is imperfect: the line-of-sight check can sometimes give a false negative with large actors (though we use some heuristics to help it out), it doesn't account for sound occlusion of ambient sounds, and so on. However, the approximation is such that its error is overwhelmed by the error inherent in a network environment with such latency and packet loss characteristics as the Internet.

Changing the definition of the relevant set in C++

The set of relevant actors for a client is determined by the C++ function ULevel::GetRelevantActors. This way, licensees who want to implement different gameplay rules are free to modify our definition of the relevant set by modifying ULevel::GetRelevantActors or (better yet) subclassing ULevel, and overriding the function.

Actor Prioritization

In deathmatch games on modem-based Internet connections, there is almost never enough bandwidth available for the server to tell each client everything it desires to know about the game state, Unreal uses a load-balancing technique that prioritizes all actors, and gives each one a "fair share" of the bandwidth based on "how important" it is to gameplay.

Each actor has a floating point variable called NetPriority. The higher the number, the more bandwidth that actor receives relative to others. An actor with a priority of 2.0 will be updated exactly twice as frequently as an actor with priority 1.0. The only thing that matters with priorities is their ratio; so obviously you can't improve Unreal's network performance by increasing all of the priorities. Some of the values of NetPriority we have assigned in our performance-tuning are:

  • Bots: 8.0
  • Movers: 7.0
  • Projectiles: 6.0
  • Pawns: 4.0
  • Decorative creatures (such as fish): 2.0
  • Decorations: 0.5

Overview of Replication

Three Types of Replication

The network code is based on three primitive, low-level replication operations for communicating information about the game state between the the server and clients:

  • Actor replication. The server identifies the set of "relevant" actors for each client (actors which are either visible to the client or are likely to somehow affect the client's view or movement instantaneously), and tells the client to create and maintain a "replicated" copy of that actor. While the server always has the authoritative version of that actor, at any time many clients might have approximate, replicated versions of that actor.
  • Variable replication. Actor variables that describe aspects of the game state which are important to clients can be "replicated". That is, whenever the value of the variable changes on the server side, the server sends the client the updated value.
  • Function call replication. A function that is called on the server in a network game can be routed to the remote client rather than executed locally. Alternatively, a function called on the client side may be routed to the server, rather than called locally.

To give a concrete example, consider the case where you are a client in a network game. You see two opponents running toward you, shooting at you, and you hear their shots. Since all of the game state is being maintained on the server rather than on your machine, why can you see and hear those things happening?

  • You can see the opponents because the server has recognized that the opponents are "relevant" to you (i.e. they are visible) and the server is currently replicating those actors to you. Thus, you (the client) have a local copy of those two player actors who are running after you.
  • You can see that the opponents are running toward you because the server is replicating their Location variable to you. You can see them animating because the server is replicating their animation variables to you. In other words, the server is continually feeding you new values of their Location and animation parameters, at the rate of several times per second.
  • You can hear their gunshots because the server is replicating the ClientHearSound function to you. The ClientHearSound function is called for a PlayerPawn whenever that PlayerPawn hears a sound.

So, by this point, the low-level mechanisms by which Unreal multiplayer games operate should be clear. The server is updating the game state and making all of the big game decisions. The server is replicating some actors to clients. The server is replicating some variables to clients. And, the server is replicating some function calls to clients.

It should also be clear that not all actors need to be replicated. For example, if an actor is halfway across the level and way out of your sight, you don't need to waste bandwidth sending updates about it. Also, all variables don't need to be updated. For example, the variables that the server uses to make AI decisions don't need to be sent to clients; the clients only need to know about their display variables, animation variables, and physics variables. Also, most functions executed on the server shouldn't be replicated. Only the function calls that result in the client seeing or hearing something need to be replicated. So, in all, the server contains a huge amount of data, and only a small fraction of it matters to the client--the ones which affect things the player sees, hears, or feels.

Thus, the logical question is, "How does the Unreal engine know what actors, variables, and function calls need to replicated?"

The answer is, the programmer who writes a script for an actor is responsible for determining what variables and functions, in that script, need to be replicated. And, he is responsible for writing a little piece of code called a "replication statement", in that script, to tell the Unreal engine what needs to be replicated under what conditions. For a real-world example, consider some of the things defined in the Actor class.

  • The Location variable (a vector) contains the actor's location. The server is responsible for maintaining the location, so the server needs to send that to clients. So the replication condition basically says "Replicate this if I am the server".
  • The Mesh variable (an object reference) references the mesh that should be rendered for the actor. The server needs to send that to clients, but it only needs to be sent if the actor is being rendered as a mesh, i.e. if the actor's DrawType is DT_Mesh. So the replication condition basically says "Replicate this if I am the server and the DrawType is DT_Mesh".
  • In the PlayerPawn class, there are a bunch of boolean variables that define keypresses and button presses, such as bFire and bJump. These are generated on the client side (where the input happens), and the server needs to know about them. So the replication condition basically says "Replicate this if I am a client".
  • In the PlayerPawn class, there is a ClientHearSound function that tells the player that she hears a sound. It's called on the server but, of course the sound needs be heard by the actual person playing the game, who is on the client side. So the replication condition for this function might be "Replicate this if I am the server".

From the above examples, several things should be apparent. First of all, every variable and function that might be replicated needs to have a "replication condition" attached to it, that is, an expression which evaluates to True of False, depending on whether the thing needs to be replicated. Second, these replication conditions need to be two-way: the server needs to be able to replicate variables and functions to the client, and the client needs to be able to replicate them to the server. Third, these "replication conditions" can be complex, such as "Replicate this if I'm the server and my DrawType is DT_Mesh".

Therefore, we need a general-purpose way of expressing (complex) conditions under which variables and functions should be replicated. What is the best way to express these conditions? We looked at all of the options, and concluded that UnrealScript--which is already a very powerful language for authoring classes, variables, and code--would be a perfect tool for writing replication conditions.

The UnrealScript Replication Statement

In UnrealScript, every class can have one replication statement. The replication statement contains one or more replication definitions. Each replication definition consist of a replication condition (a statement that evaluates to True or False), and a list of one or more functions and variables to which the condition applies.

The replication statement in a class may only refer to variables defined in that class, and functions defined first in that class (that is, it cannot apply to functions defined in a superclass but overridden in that class). This way, if the Actor class contains a variable DrawType, then you know where to look for its replication condition: it can only reside there in the Actor class.

It's valid for a class to not contain a replication statement; this simply means that the class doesn't define any new variables or functions that need to be replicated. In fact, most classes do not need replication statements because most of the "interesting" variables that affect display are defined in the Actor class, and are only modified by subclasses. In Unreal, we have about 500 classes, and only about 10 of them need replication statements.

If you define a new variable or function in a class, but you don't list it in a replication definition, that means that your variable or function is absolutely never replicated. This is the norm; most variables and functions don't need to be replicated.

Here is an example of the UnrealScript syntax for the replication statement. This is taken from the Pawn class:

replication
{
    // Variables the server should send to the client.
    reliable if( Role==ROLE_Authority )
        Weapon;
    reliable if( Role==ROLE_Authority && bNetOwner )
         PlayerName, Team, TeamName, bIsPlayer, CarriedDecoration, SelectedItem,
         GroundSpeed, WaterSpeed, AirSpeed, AccelRate, JumpZ, MaxStepHeight,
         bBehindView;
    unreliable if( Role==ROLE_Authority && bNetOwner && bIsPlayer && bNetInitial )
        ViewRotation;
    unreliable if( Role==ROLE_Authority && bNetOwner )
        Health, MoveTarget, Score;

    // Functions the server calls on the client side.
    reliable if( Role==ROLE_Authority && RemoteRole==ROLE_AutonomousProxy )
        ClientDying, ClientReStart, ClientGameEnded, ClientSetRotation;
    unreliable if( Role==ROLE_Authority )
        ClientHearSound, ClientMessage;
    reliable if( Role<ROLE_Authority )
        NextItem, SwitchToBestWeapon, bExtra0, bExtra1, bExtra2, bExtra3;

    // Input sent from the client to the server.
    unreliable if( Role<ROLE_AutonomousProxy )
        bZoom, bRun, bLook, bDuck, bSnapLevel, bStrafe;
    unreliable always if( Role<=ROLE_AutonomousProxy )
        bFire, bAltFire;
}

The key things you see here are:

  • The replication statement is enclosed by "replication {}".
  • Each replication definition begins with "reliable if (condition)" or "unreliable if (condition)".

Reliable vs. Unreliable

Functions replicated with the "unreliable" keyword are not guaranteed to reach the other party and, if they do reach the other party, they may be received out-of-order. The only things which can prevent an unreliable function from being received are network packet-loss, and bandwidth saturation. So, you need to understand the odds, which we will grossly approximate here. The results vary wildly among different types of network, so we can make no guarantees:

  • In a LAN game, we guesstimate that unreliable data is received successfully approximately 99% of the time. However, in the course of a game, hundreds of thousands of things are replicated, so you can be sure that some unreliable data will be lost. Therefore, even if you're aiming for LAN performance only, your code needs to handle your unreliably replicated variables gracefully in the case that they are lost over the wire.
  • In a typical low quality 28.8K ISP connection, unreliable data is generally received 90%-95% of the time. In other words, it is very frequently lost.

To get a better feeling for the tradeoffs between reliable and unreliable functions, check out the replication statements in the Unreal scripts, and gauge their importance vs. the reliability decision we made.

Variables are always reliable

The "reliable" and "unreliable" keywords are ignored for variables. Variables are always guaranteed to reach the other party eventually, even under packet-loss and bandwidth saturation conditions. Changes in such variables are not guaranteed to reach the other party in the same order in which they were sent.

Summary

Here, we have documented the syntax of the replication statement thoroughly, without saying much about the meaning of the expressions like "Role==ROLE_Authority" and "bNetOwner". This is covered in the next section.

Replication Conditions

Here is a simple example of a replication condition within a class's script:

replication
{
    reliable if( Role==ROLE_Authority )
        Weapon;
}

This replication condition, translated into English, is "If the value of this actor's Role variable is equal to ROLE_Authority, then this actor's Weapon variable should be reliably replicated to all clients for whom this actor is relevant".

A replication condition may be any expression that evaluates to a value of True or False (that is, a boolean expression). So, any expression you can write in UnrealScript will do--including comparing variables, calling functions, and combining conditions using the boolean !, &&, ||, and ^^ operators.

An actor's Role variable generally describes how much control the local machine has over the actor. ROLE_Authority means "this machine is the server, so it is completely authoritative over the proxy actor". ROLE_SimulatedProxy means "this machine is a client, and it should simulate (predict) the physics of the actor". ROLE_DumbProxy means "this machine is a client and it should not do any simulation on this proxy actor". Role is described in more detail in a later section, but the quick summary is this:

  • if ( Role==ROLE_Authority ): means "If I am the server, I should replicate this to clients".
  • if( Role<ROLE_Authority ): means "If I am a client, I should replicate this to the server.

The following variables are very often used in replication statements because of their high utility:

  • bIsPlayer: Whether this actor is a player. Is True for players, false for all other actors.
  • bNetOwner: Whether this actor is owned by the client for whom the replication condition is being evaluated. For example, say Fred is holding a DispersionPistol, and Bob isn't holding any weapon. When the DispersionPistol is being replicated to Fred, its bNetOwner variable will be True (because Fred owns the weapon). When it is being replicated to Bob, its bNetOwner variable will be False (because Bob does not own the weapon).
  • bNetInitial: Valid only on the server side, i.e. if Role==ROLE_Authority. Indicates whether this actor is being replicated to the client for the first time. This is useful for clients with Role==ROLE_SimulatedProxy, because it enables the server to sent their location and velocity just once, with the client subsequently predicting it.

Replication condition guidelines:

  • Since variables are typically replicated one-way (either from the client to the server, or from the server to the client, but never both), all replication conditions generally start with a comparison of Role or RemoteRole, i.e. if( Role==ROLE_Authority ) or if( RemoteRole<ROLE_SimulatedProxy ). If a replication condition doesn't contain a comparison of Role or RemoteRole, there is probably something wrong with it.
  • Replication conditions are evaluated very, very frequently on the server during network play. Keep them as simple as possible, but no simpler.
  • While replication conditions are allowed to call functions, try to avoid that because it could be a big slowdown.
  • Replication conditions shouldn't have any side-effects, because the network code may choose to call them at any time including times when you don't expect. For example if you do something like if( Counter++ > 10 )..., good luck trying to figure out what the hell is going to happen..

Variable Replication

Update mechanism

After every tick, the client and the server check out all actors in their relevant set. All of their replicated variables are examined to see if they have changed since the previous update, and the variables' replication conditions are evaluated to see if the variables need to be sent. As long as there is bandwidth available in the connection, those variables are sent across the network to the other machine.

Thus, the client receives updates of the "important" events that are happening in the world, which are visible or audible to that client. The key points to remember about variable replication are:

  • Variable replication occurs only after a tick completes. Therefore, if in the duration of a tick, a variable changes to a new value, and then it changes back to its original value, then that variable will not be replicated. Thus, clients only hear about the state of the server's actor's variables after its tick completes; the state of the variables during the tick is invisible to the client.
  • Variables are only replicated when they change, relative to their previously known value.
  • Variables for an actor are only replicated to a client when they are in the client's relevant set. Thus, the client does not have accurate variables for actors that are not in his relevant set.
  • UnrealScript has no concept of global variables; so they only variables that can be replicated are instance variables belonging to an actor.

Variable type notes

  • Vectors and Rotators: To improve bandwidth efficiency, Unreal quantizes the values of vectors and rotators. The X,Y,Z components of vectors are converted to 16-bit signed integers before being sent, thus any fractional values or values out of the range -32768..32767 are lost. The Pitch,Yaw,Roll components of vectors are converted to bytes, of the form (Pitch>>8)&255. So, you need to be careful with vectors and rotators. If you absolutely must have full precision, then use int or float variables for the individual components; all other data types are sent with their complete precision.
  • General structs are replicated by sending all of their components. A struct is sent as an "all or nothing" type of thing.
  • Arrays of variables can be replicated, but only of the size of the array (in bytes) is less than 448 bytes.
  • Arrays are replicated efficiently; if a single element of a large array changes, only that element is sent.

Function Call Replication

Remote Routing Mechanism

When an UnrealScript function is called during a network game, and that function has a replication condition, the condition is evaluated and execution progresses as follows:

  • If the function's replication condition evaluates to True, the function call is sent to the machine on the other side of the network connection for execution. In other words, the function's name, and all of its parameters, are crammed together into a packet of data, and transmitted to the other machine for later execution. When this occurs, the function returns immediately and execution continues on. If the function were declared to return a value, then its return value is set to zero (or the equivalent of zero in some other type, i.e. 0,0,0 for vectors, None for objects, etc). Any out parameters are left unaffected. In other words, UnrealScript never sits around waiting for a replicated function call to complete, so it can never deadlock. Rather, replicated function calls are sent off for the remote machine to execute, and the local code continues executing.
  • If the replication condition evaluates to False, the function is executed normally on the local machine.

Unlike replicated variables, a function call on an actor can only be replicated to the player who owns that actor. So, replicated functions are only useful in subclasses of PlayerPawn (i.e. players, who own themselves) and subclasses of Inventory (i.e. weapons and pickup items, who are owned by the player who is currently carrying them). That is to say, a function call can only be replicated to one actor (the player who owns it); they cannot be multicast.

Unlike replicated variables, replicated function calls are sent to the remote machine immediately when they are called, and they are always replicated regardless of bandwidth. Thus, it is possible to flood the available bandwidth if you make too many replicated function calls. Replicated functions suck away however much bandwidth is available, and then whatever bandwidth is left over is used for replicating variables. Therefore, if you flood the connection with replicated functions, you can starve the variables, which visually results in not seeing other actors update, or seeing them update in an extremely choppy motion.

In UnrealScript, there are no global functions, so there is no concept of "replicated global functions". A function is always called in the context of a particular actor.

Replicated Function Calls vs. Replicated Variables

  • Too many replicated functions can flood the available bandwidth (because the are always replicated, regardless of available bandwidth), whereas replicated variables automatically are throttled and parceled out according to bandwidth available.
  • Function calls are replicated only during UnrealScript execution when they are actually called, whereas variables are replicated only at the end of the current tick when no script code is executing.
  • Function calls on an actor are only replicated to the client who owns that actor, whereas an actor's variables are replicated to all clients for whom that actor is relevant.

Quantization Gotchas

To improve bandwidth efficiency, Unreal quantizes the values of vectors and rotators. The X,Y,Z components of vectors are converted to 16-bit signed integers before being sent, thus any fractional values or values out of the range -32768..32767 are lost. The Pitch,Yaw,Roll components of vectors are converted to bytes, of the form (Pitch>>8)&255. If you need complete accuracy on rotators and vectors, send them as individual float or int components.

Actor Roles

The Actor class defines the ENetRole enumeration and two variables, Role and RemoteRole, as follows:

// Net variables.
enum ENetRole
{
    ROLE_None,            // Means the actor is not relevant in network play.
    ROLE_DumbProxy,       // A dumb proxy.
    ROLE_SimulatedProxy,  // A simulated proxy.
    ROLE_AutonomousProxy, // An autonomous proxy.
    ROLE_Authority,       // The one authoritative version of the actor.
};
var ENetRole Role;
var(Networking) ENetRole RemoteRole;

The Role and RemoteRole variables describes how much control the local and remote machines, respectively, have over the actor:

  • Role==ROLE_DumbProxy means the actor is a temporary, approximate proxy which should not simulate any physics at all. On the client, dumb proxies just sit around and are only moved or updated when the server replicates a new location, rotation, or animation information.
    • This situation is only seen in network clients, never for network servers or single-player games.
  • Role==ROLE_SimulatedProxy means the actor is a temporary, approximate proxy which should simulate physics and animation. On the client, simulated proxies carry out their basic physics (linear or gravitationally-influenced movement and collision), but they don't make any high-level movement decisions. They just go.
    • This situation is only seen in network clients, never for network servers or single-player games.
  • Role==ROLE_AutonomousProxy means the actor is the local player. Autonomous proxies have special logic built in for client-side prediction (rather than simulation) of movement.
    • This situation is only seen in network clients, never for network servers or single-player games.
  • Role==ROLE_Authority means this machine has absolute, authoritative control over the actor.
    • This is the case for all actors in single-player games.
    • This is the case for all actors on a server.
    • On a client, this is the case for actors that were locally spawned by the client, such as gratuitous special effects which are done client-side in order to reduce bandwidth usage.

On the server side, all actors have Role==ROLE_Authority, and RemoteRole set to one of the proxy types. On the client side, the Role and RemoteRole are always the exactly reversed relative to the server's value. This is as expected from the meaning of Role and RemoteRole.

Most of the meaning of the ENetRole values is defined by the replication statements in the UnrealScript classes such as Actor and PlayerPawn. Here are several examples of how the replication statements define the meanings of the various role values:

  • The Actor.AmbientSound variable is sent from the server to clients because of this replication definition in the Actor class: reliable if( Role==ROLE_Authority ) AmbientSound;
  • The Actor.AnimSequence variable is sent from the server to clients, but only for actors rendered as meshes, because of this replication definition in the Actor class: unreliable if( DrawType==DT_Mesh && (RemoteRole<=ROLE_SimulatedProxy) ) AnimSequence;
  • The client replicates his Fire and AltFire function calls to the server because of this replication definition in the PlayerPawn class: unreliable if( Role<ROLE_Authority ) Fire, AltFire;
  • The server sends clients the Velocity of all simulated proxies when they are initially spawned and all moving brushes because of this replication definition in the Actor class: unreliable if( (RemoteRole==ROLE_SimulatedProxy && (bNetInitial || bSimulatedPawn)) || bIsMover ) Velocity;

By studying the replication statements in all of the UnrealScript classes, you can understand the inner workings of all of the roles. There is really very little "behind-the-scenes magic" going on with respect to replication: At a low C++ level, the engine provides a basic mechanism for replicating actors, function calls, and variables. At the high UnrealScript level, the meanings of the various network roles are defined by specifying what variables and functions should be replicated based on the various roles. So, the meaning of the roles is almost self-defining in UnrealScript, with the exception of a small amount of behind-the-scenes C++ logic which conditionally updates physics and animation for simulated proxies.

What Exactly Is Happening Behind The Scenes

The answer is for licensees to do a "Find in Files" in Visual C++ for all occurrences of "ROLE_" in the C++ and UnrealScript files. While documentation provides a general understanding of how network roles are interpreted, the exact impact of roles on all aspects of the code can only be completely described by the source code.

Simulated Functions

On the client side, many actors exist in the form of "proxies", meaning approximate copies of actors created by the server, and sent to the client to provide a visually and aurally reasonable approximation of what the client sees during gameplay.

On the client, these proxy actors are often moving around using client-side physics and affecting the environment, so at any time their functions can potentially be called. For example, a simulated proxy TarydiumShard projectile might run into a dumb proxy Tree actor. When actors collide, the engine attempts to call their Touch functions to notify them of the collision. Depending on context, the client desires to execute some of these functions calls, but ignore others. For example, a Skaarj's Bump function should not be called on the client side, because his Bump function attempts to carry out gameplay logic, and gameplay logic should only occur on the server. So, the Skaarj's Bump function should not be called. However, a TarydiumShard projectile's Bump function should be called, because it stops the physics and spawns a client-side special effect actor.

UnrealScript functions can optionally be declared with the "simulated" keyword to give programmers fine-grained control over which functions should be executed on proxy actors. For proxy actors (that is, actors with Role<ROLE_Authority), only functions declared with the "simulated" keyword are called. All other functions are skipped.

Here is an example of a typical simulated function:

simulated function HitWall( vector HitNormal, actor Wall )
{
        SetPhysics(PHYS_None);
        MakeNoise(0.3);
        PlaySound(ImpactSound);
        PlayAnim('Hit');
}

So, "Simulated" means "this function should always be executed for proxy actors".

Player Prediction

Overview

If a pure client-server model were used in Unreal, player movement would be very laggy. On a connection with 300 msec ping, when you push the forward key, you wouldn't see yourself move for 300 msec. When you pushed the mouse left, you wouldn't see yourself turn for 300 msec. This would be really frustrating.

To eliminate client-movement lag, Unreal uses a prediction scheme similar to that pioneered by QuakeWorld. It must be mentioned that the player prediction scheme is implemented entirely in UnrealScript. It is a high-level feature implemented in the PlayerPawn class, rather than a feature of the network code: Unreal's client movement prediction is layered entirely on the general-purpose replication features of the network code.

Inner Workings

You can see exactly how Unreal's player prediction works by examining the PlayerPawn script. Since the code is somewhat complex, its workings are briefly described here.

The approach can best be described as a lock-step predictor/corrector algorithm. The client takes his input (joystick, mouse, keyboard) and physical forces (gravity, buoyancy, zone velocity) into account and describes his movement as a 3D acceleration vector. The client sends this acceleration along with various input related information and his current timestamp (the current value of Level.TimeSeconds on the client side) to the server in a replicated ServerMove function call:

function ServerMove
(
    float TimeStamp,
    float AccelX,
    float AccelY,
    float AccelZ,
    float LocX,
    float LocY,
    float LocZ,
    byte MoveFlags,
    eDodgeDir DodgeMove,
    rotator Rot,
    int ViewPitch,
    int ViewYaw
);

Then the client calls his MoveAutonomous to perform this same identical movement locally, and he stores this movement in a linked list of remembered movements using the SavedMove class. As you can see, if the client never heard anything back from the server, the client would be able to move around with zero lag just as in a single-player game.

When the server receives a ServerMove function call (replicated across the network), the server carries out the exact same movement on the server immediately. It deduces the movement's DeltaTime from the current ServerMove's TimeStamp and the previous one's. In this way, the server is carrying out the same basic movement logic as the client. However, the server might see things slightly different than the client. For example, if there's a monster running around, the client might have thought it was in a different position than the server (because the client is only in rough approximate sync with the server). Thus, the client and the server might disagree about how far the client actually moved as a result of the ServerMove call. At any rate, the server is authoritative, and he is completely responsible for determining the client's position. Once the server has processed the client's ServerMove call, it calls the client's ClientAdjustPosition function which is replicated across the network to the client:

function ClientAdjustPosition
(
    float TimeStamp,
    name newState,
    EPhysics newPhysics,
        float NewLocX,
    float NewLocY,
    float NewLocZ,
    float NewVelX,
    float NewVelY,
    float NewVelZ
);

Now, when the client receives a ClientAdjustPosition call, he must respect the server's authority over his position. So, the client sets his exact location and velocity to that specified by the ClientAdjustPosition call. However, the position the server specifies in ClientAdjustPosition reflects the client's actual position at some time in the past. But, the client wants to predict where he is supposed to be at the present moment. So, now the client goes through all of the SavedMove's in his linked list. All moves earlier than the ClientAdjustPosition call's TimeStamp are discarded. All moves that occurred after TimeStamp are then re-run by looping through them and calling MoveAutonomous for each one.

This way, at any point in time, the client is always predicting ahead of what the server has told him by an amount of time equal to half his ping time. And, his local movement is not at all lagged.

Advantages

This approach is purely predictive, and it gives one the best of both worlds: In all cases, the server remains completely authoritative. Nearly all the time, the client movement simulation exactly mirrors the client movement carried out by the server, so the client's position is seldom corrected. Only in the rare case, such as a player getting hit by a rocket, or bumping into an enemy, will the client's location need to be corrected.

The GameInfo class

The UnrealScript GameInfo class implements the game rules. A server (both dedicated and single-player) has one GameInfo subclass, accessible in UnrealScript as Level.Game. For each game type in Unreal, there is a special GameInfo subclass. For example, some existing classes are DeathmatchGame, SinglePlayer, TeamGame.

A client in a network game does not have a GameInfo. That is, Level.Game==None on the client side. Clients should not be expected to have a GameInfo because the server implements all of the gameplay rules, and the generality of the code calls for the client not knowing what the game rules are.

GameInfo implements a broad set of functionality, such as recognizing players coming and going, assigning credit for kills, determining whether weapons should respawn, and so on. Here, we will only look at the GameInfo functions which are directly related to network programming.

InitGame

event InitGame( string[120] Options, out string[80] Error );

Called when the server (either in network play or single-player) is first started up. This gives the server the opportunity to parse the startup URL options. For example, if the server was started with "Unreal.exe MyLevel.unr?game=unreali.teamgame", the Options string is "?game=unreali.teamgame". If Error is set to a non-empty string, the game fails with a critical error.

PreLogin

event PreLogin( string[120] Options, out string[80] Error );

Called immediately before a network client is logged in. This gives the server an opportunity to reject the player. This is where the server should validate the player's password (if any), enforce the player limit, and so on.

Login

event playerpawn Login( string[32] Portal, string[120] Options, out string[80] Error, class<playerpawn> SpawnClass );

The Login function is always called after a call to PreLogin which does not return an error string. It is responsible for spawning the player, using the parameters in the Options string. If successful, it should return the PlayerPawn actor it spawned.

If the Login function returns None indicating that the login failed, then it should set Error to a string describing the error. Failing a Login should be used only as a last resort. If you are going to fail a login, it is more efficient to fail it in PreLogin rather than Login.

Bandwidth Performance Tips

Optimization goal

The goal here is to maximize the amount of visibly important detail that is sent with a given bandwidth limit. With the bandwidth limit determined at runtime, your goal in writing scripts for actors that are used in multiplayer games is to keep bandwidth use to a minimum. The techniques we use in our scripts include:

  • Use ROLE_SimulatedProxy and simulated movement whenever possible. For example, nearly all of the Unreal projectiles use ROLE_SimulatedProxy. The one exception is the Razorjack alt-fire blades, which the player can steer during gameplay, thus the server must continually update the position to clients.
  • For quick special effects, spawn the special effects actors purely on the client side. For example, many of our projectiles use a simulated HitWall function to spawn their effects on the client-side. Since these special effects are just decorative rather than affecting gameplay, there is no drawback to doing them completely on the client side.
  • Fine tune the default NetPriority for each class. Projectiles and players need to have high priorities, purely decorative effects can have lower priorities. The defaults that Unreal provides are good first-pass guesses, but you can always gain some improvement by fine-tuning them.
  • When an actor is first replicated to a client, all of its variables are initialized to their class default values. Subsequently, only variables that differ from their most recent known values are replicated. Thus, you should design your classes so that as many variables as possible are automatically set to their class defaults. For example, if an actor always should have a LightBrightness value of 123, there are two ways you can make that happen: (1) set the class default's value of LightBrightness to 123, or (2) in the actor's BeginPlay function, initialize LightBrightness to 123. The first approach is more efficient, because the LightBrightness value will never need to be replicated. With the second approach, the LightBrightness needs to be replicated each time an actor first becomes relevant to the client.

Traffic Monitoring

To monitor network traffic, licensees can compile the engine with:

#define DO_SLOW_GUARD 1

This enables network statistic gathering. Then, comment out the line Suppress[#]=DevNetTraffic in Unreal.ini. Then, a complete summary of network data received by the machine will be written to the log. In other words, do this on the client side to see the data sent by the server. Do it on the server side to see the data sent by the client. The data is written to the log in a very verbose format, giving timestamps for all packets, along with a summary of all replicated actors, variables, and function calls.

Network Driver Implementation

Plug-in Network Drivers

Unreal's network support is generalized through a plug-in interface based on the C++ UNetDriver class. The Unreal engine deals with all networking issues through the UNetDriver class, and dynamically loads the appropriate network driver specified in Unreal.ini, which defaults to:

[Engine.Engine]
NetworkDevice=IpDrv.TcpNetDriver

Unreal's current Internet support is the UDP network driver, named TcpNetDriver. However, it is quite possible to support new kinds of networks by creating new subclasses of UNetDriver, and using the TcpNetDriver source as a guideline for how to implement the new functions. In fact, the Maverick Software team has created an AppleTalk driver for the Mac version of Unreal using this interface.

The network driver is responsible for opening connections, closing connections, sending data, and receiving unreliable data. However, the contents of the data is defined by the Unreal Wire Protocol, and is completely opaque to the network driver itself. Thus, UNetDriver has no idea what information it's communicating, it just sends and receives it blindly. Its characteristics are as follows:

  • Connection-oriented. UNetDriver is responsible for maintaining a list of connections defined by UNetConnection subclasses. When UNetDriver is layered on top of a connectionless protocol (such as UDP), it must contain its own internal logic for maintaining connections, handling their timeouts, etc.
  • UNetDriver is packet-oriented, rather than stream-oriented. All data sent and received through UNetDriver exists in discrete packets of size 0...MAX_PACKET_SIZE.
  • Packets are sent unreliably. All reliable sending and receiving of packets is performed at a higher level which is invisible to UNetDriver. A packet sent from one machine to another might not arrive, might arrive once, or might arrive multiple times. Additionally, packets might arrive out of order or with significant delay.
  • Packets are never corrupted. When a packet is received, it is guaranteed that the size and contents received are identical to the size and contents that were sent.

Internet Driver

Unreal's Internet support is based on UDP, the standard Internet protocol for unreliable, connectionless communication. All Unreal gameplay coordination between a client and server goes through one constant, unchanging pairing of UDP addresses (where the client and server each have a 32-bit Internet address and a 16-bit port number). The default port number can be seen in Unreal.ini.

Thus, Unreal's UDP packets are extremely easy to proxy, and they can be proxied transparently without the proxy having to know anything about their contents.

Unreal Wire Protocol

The Unreal Wire Protocol defines the contents of packets as a stream of bits. The protocol deals with a variety of concepts, such as replicating variables and functions, creating actors, destroying actors, transmitting files, and exchanging packets reliably and unreliably (both types are used in various circumstances).

The protocol will undergo some major changes in the coming months to improve efficiency and reliability, so it would not be useful to document it here and now.

It must be mentioned that the protocol is closely tied to the Unreal package file format described in the Package Documentation so it will be quite difficult to parse and do anything useful with.

UnrealScript: UdpLink, TcpLink

Unreal's TcpLink and UdpLink scripts enable you to write, in UnrealScript, code for actors which are able to communicate with external programs. These are the optimal way of extending Unreal with cool new networking features. For example, some of the cool things one could do are:

  • Write "event gateways" which forward events (such as players pressing buttons, walking into zones, etc) to other servers.
  • Write server-side programs to interface the server to master servers, statistic trackers, and so on.
  • Write server-side programs to maintain persistent player statistics or inventory. For example, you could write a Java/C++ database style "player account manager" program that keeps track of player names, passwords, and their inventory for players. Then, you can write an UnrealScript class to interface to the account manager by TCP or UDP and validate players that are trying to log in. See GameInfo.Login, TcpLink, and UdpLink for ideas.
  • Write client-side chat programs.

The Present and The Future

The words one might use to describe Unreal's networking architecture are "powerful", "general", "complex" and "hard to master". The architecture went through a tremendous amount of evolution during the game's development, to arrive at the current solution which is a balance between power, simplicity, and the pragmatic need to solve certain problems.

The ideal networking architecture, from an ease-of-programming standpoint, is the pure client-server model, where the client truly acts as a dumb rendering terminal, and receives a display list from the server. However, as discussed previously, the analysis of the rate of bandwidth improvement versus hardware improvement indicates that we live in a world where the pure client-server model will be impractical for the foreseeable future.

Thus, the ability to provide rich client-side simulation of physics and script execution in general is tantamount in any next-generation networking engine. In Unreal we have defined a generalized networking model based on the generalized replication of objects, object variables, and object function calls. This model provides rich simulation capabilities without being hardcoded to any particular simulation model.

I'm pretty sure that this broad networking architecture for Unreal is the right one. Some of the research areas I investigated while determining the current direction include database replication, Unix RPC, the CORBA distributed object model, and Java RPC. My general conclusion is that, though there are some cool ideas out there, nobody else is really pushing the limitations of Internet technology as much as game developers. The same can probably be said about other research areas, such as real-time 3D.

As for the future, there are a lot of areas where this model can be extended and improved. The addition of multicast replicated functions would increase the amount of simulation that can be done without variable replication. An extended peer proxy model could enable the creation of a server backbone enabling the realistic real-time flow of NPC objects between servers. The replicated object model could be extended to other areas of the engine, such as the user-interface and chat system. There is a tremendous amount of promise for this architecture to be applied to much richer, more persistent game environments such as the worlds of Ultima Online, while retaining the distributed, user-modifiable nature of the system. In the coming years, networking will be an extremely interesting area of game development.

-Tim Sweeney

End


Unreal Packages

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Level Designers, UnrealScript Programmers, C++ Programmers.
Last Updated: 01/25/02

About this document

This document has been written with our licensees in mind (Microprose, Ion Storm, Legend, and others). However, much of the info is useful to the Unreal community, so I am releasing it here unedited. The sections that refer to C++ code are not relevent to the community because we aren't releasing the C++ source. But, there is still a lot of useful information here.

Overview

An Unreal "package" is a collection of related objects such as textures, sound effects, and scripts which are grouped together for convenient distribution and use.

For example, in Unreal, textures are stored in texture package files, which use the ".utx" extension. A .utx file contains many (tens or hundreds) of textures which are part of a similar theme, such as the "SkyCity.utx" texture package.

Unreal's file format is based on packages because packages enable the game engine and content to be developed modularly. Artists maintain their textures in .utx files; the programmers working on the engine and game maintain separate packages of UnrealScript classes; people in the Unreal community can create and distribute their own packages online; and so on.

One package may refer to objects which are contained in another package. For example, an .unr level package may refer to textures which reside in various external .utx files; sounds in other .uax files; and music in a .umx file. We say that the level file is "dependent" on the other packages. To load that .unr level file successfully, you need to have all of the other .utx, .uax, and .umx files which that level refers to. If one of those packages is missing, you will not be able to load the .unr file.

Package files

All Unreal package files are stored in the same binary file format, but they use different extensions to identify their type:

  • .utx files are packages of textures.
  • .uax files are packages of audio (sound effects).
  • .umx files are packages of music.
  • .unr files contain one game level.
  • .u files are packages containing UnrealScript classes and objects (like textures, sounds, and meshes) they contain.

When the Unreal engine needs to load a package, it looks in the subdirectories listed in the [Core.System] section, in the Path#= list. The relevent lines of the clean (unmodified) Unreal.ini file look like this:

[Core.System]
CachePath=..\Cache
CacheExt=.uxx
Paths[0]=..\System\*.u
Paths[1]=..\Maps\*.unr
Paths[2]=..\Textures\*.utx
Paths[3]=..\Sounds\*.uax
Paths[4]=..\Music\*.umx

When you try to load a package by its raw name (such as "SkyCity"), the engine first searches in the CachePath for a matching package downloaded from the Internet; then it searches in each of the numbered directories in order (0, 1, 2...) for matching files. For example, it looks for \Unreal\Cache\[some funky name].uxx, then \Unreal\System\SkyCity.u, then \Unreal\Maps\SkyCity.unr, then \Unreal\Textures\SkyCity.utx -- and the file \Unreal\Textures\SkyCity.utx does exist, so it uses that file.

Because of this storage and search scheme, you must not create two packages with the same base name, which only differ by extension. For example, you must not create a texture file named SkyCity.utx and a music file named SkyCity.umx. If you do that, the engine will always fail to load one of the packages and give an error.

All Unreal package files (.utx, .uax, .umx, .unr, and .u) use the exact same file format, and are processed in exactly the same way by the engine. The only reason we define different extensions is for convenience, and to interoperate with Windows cleanly. For example, .unr files are known to contain levels, so we associate the Unreal icon with them, and set them up so right-clicking on an .unr file in Windows launches Unreal. And, UnrealEd knows that .utx files contain textures. The meanings of these file extensions are purely superficial. They all use the same file format.

Internet package file downloading and caching

Whenever you save a package file to disk, the file is internally stamped with a GUID ("Globally Unique Identifier"), which is a 128-bit number which is guaranteed to be unique. In single-player play, this GUID is never used and is irrelevent. However, when you connect to an Internet-based server, the server sends a list of packages that are required for gameplay there (for example, the level it uses, any texture packages it uses, any sound packages, etc). These packages are identified by name and GUID. If you don't have one of the packages required by the server, the package file is automatically downloaded to your \Unreal\Cache directory, and given a filename based on its GUID.

A typical \Unreal\Cache directory looks something like this:

Directory of F:\Unreal\Cache

06/02/98 03:37a <DIR> .
06/02/98 03:37a <DIR> ..
06/02/98 03:37a 8,932 2306087A11D1E2FD4F00DBA5CAA00349.uxx
06/02/98 03:38a 8,932 2401042A11D1E2FD4F00DBA5CAA00381.uxx
3 File(s) 8,932 bytes
698,601,472 bytes free

Packages stored in the \Unreal\Cache directory are identified by their GUID rather than the package name given to them by their creator, to avoid conflicting names. For example, there are bound to be a ton of levels on the net called Test.unr, a ton of textures named Walls.utx, etc. The GUID scheme avoids conflicts.

In UnrealEd, each time a package file is saved, it is assigned a new GUID. This way, each version of a package is guaranteed to be tracked and cached separate from other versions. This is good, because it prevents people from trying to play on a server using different versions of a level. This is bad, because if you simply load a texture file, resave it, and copy it to your UnrealServer, all of the players who come to your server will have to re-download the package. Therefore, we recommend modifying your package files only when necessary, and releasing them only after enough testing and use that you know they're not going to change and force redownloading a day later -- especially with large package files.

Why Unreal is based on packages

  • Packages enable an open plug-in architecture for easy community and licensee extensibility.
  • Packages make the Unreal engine expandable in content, UnrealScript code, and C++ code.
  • Packages help to improve the modularity of the code and reduce interdependencies.
  • Packages make it much easier for licensees to separarate the Unreal engine from the Unreal game.
  • Packages simplify Web-style downloading of content in Internet play.

Standard class packages that ship with Unreal

Core | The high-level framework Unreal is built on, similar to the MFC core or the Java Virtual Machine. The Core package contains the definitions of object, class, subsystem, script, property, name, and the object manager. The core is indepenent of any notion of a game or 3d engine.
Engine | The Unreal 3d engine, including support for vector math, actors, physics, collision, interaction, cameras, and networking.
Editor | The UnrealEd 3d editing environment with geometry editing, realtime lighting, and actor editing support.
Render | The Unreal rendering engine implementation.
Window | The platform-specific code supporting Unreal.
Galaxy | The implementation of Unreal's sound system (UAudioSubsystem) running on top of the Galaxy sound system for Windows. It is possible (for example, when porting Unreal to another platform) to completely replace the Galaxy package with an implementation of another sound system.
GlideDrv | Unreal 3d hardware support code for 3dfx's Glide library.
UnrealI | The Unreal I game implementation.
WinDrv | Windows viewport and client driver.
SoftDrv | Software rendering driver.
Fire | Fractal fire and water effects.
IpDrv | TCP/IP networking driver.

Licensees: Unreal package usage

Licensees may use all our .u packages except UnrealI verbatim or you may modify them to fit your needs. Bear in mind that it is attractive to use them in an unmodified form, as that makes merging with future code updates much easier and makes it easy to isolate problems in each others' code.

Licensees may use the UnrealI package as a reference and for internal development use, but the content in UnrealI is specific to our particular game, and it mustn't be used in your final product.

Licensees should create one more more new packages, for example "WheelOfTime" for their game-specific content. Keep in mind that your package and UnrealI can exist side-by-side during your development cycle until you've fully migrated away from the UnrealI specific content.

Licensee programmers: Sample directory layout for the "Engine" package

Here is an example of the directory structure for all the files that are related to the "Engine" package. The other packages follow a similar structure.

Distributable files:

\Unreal\System\Engine.dll | The package's C++ DLL file.
\Unreal\System\Engine.u | The package's UnrealScript class file.

Developer files:

\Unreal\Engine\Inc\Engine.h | Main public header file for the engine package.
\Unreal\Engine\Inc\*.* | Various public header files for the engine package, included by Engine.h.
\Unreal\Engine\Src\EnginePrivate.h | Private implementation header file.
\Unreal\Engine\Src\EngineClasses.h | Scripted classes exported to C++.
\Unreal\Engine\Src\Engine.cpp | Generates the package's precompiled header file.
\Unreal\Engine\Src\*.* | Various C++ files comprising the engine's code.
\Unreal\Engine\Lib\Engine.lib | The export library for linking with the engine.
\Unreal\Engine\Classes\*.uc | The UnrealScript classes used in building Engine.u.
\Unreal\Engine\Textures\*.* | Graphics files used in building Engine.u.
\Unreal\Engine\Models\*.* | Model files used in building Engine.u.
\Unreal\Engine\Sounds\*.* | Sound files used in building Engine.u.

Licensee programmers: Associating packages and DLL's

When you declare an UnrealScript class as "intrinsic", the engine looks in the .DLL file corresponding to the class's package for the class's corresponding C++ code. For example, here is the declaration of the "PlayerPawn" class in the "Engine" package:

//=============================================
// PlayerPawn.
//=============================================
class PlayerPawn expands Pawn
    intrinsic;

(You can find the above code in the file \Unreal\Engine\Classes\PlayerPawn.uc.)

When you declare a class as "intrinsic" in UnrealScript, you are telling the engine that you have created some corresponding C++ code for the class. In this way, you can mix and match UnrealScript and C++ code when you write your game code.

When you declare "intrinsic" classes, Unreal looks for the .DLL file in the \Unreal\System directory whose name matches your package's name. For example, to find the C++ implementation of the PlayerPawn class, Unreal looks in the "\Unreal\System\Engine.dll" file.

In C++, you must use the IMPLEMENT_INTRINSIC macro (defined in UnObjBas.h) to tell the engine that you have implemented a new class in C++. Internally, this macro generates some __declspec(DLL_EXPORT) declarations that Unreal looks for in your DLL. For example, the PlayerPawn class is exposed in the source file "\Unreal\Engine\UnPawn.cpp" as follows:

IMPLEMENT_CLASS(APlayerPawn);

In addition, once per package you need to use Unreal's package declaration macro to expose the package:

IMPLEMENT_Package(Engine);

So, to summarize:

  • Each Unreal package corresponds to a .u file, for example, "\Unreal\System\MyPackage.u".
  • If one or more classes in the package are "intrinsic" classes, then Unreal expects to find a C++ .DLL file corresponding to the package, for example, "\Unreal\System\MyPackage.dll".
  • Unreal dynamically loads and unloads packages and their optional, corresponding .DLL files, on the fly -- they are loaded and unloaded based on whether they are needed in the current game level.

Licensee programmers: Running the game and editor without the UnrealI.u package

You can start working with the "baseline" version of the Unreal engine (that is, the engine with all game-specific content removed), with:

    unreal.exe level.unr?class=engine.playerpawn?class=engine.gameinfo

While you're playing with the baseline configuration, you won't be able to see the player model and you won't be able to use any weapons because, of course, all of those things are game-specific and stored in the UnrealI package. But, the point is, you can edit and play levels with only the baseline engine, without any of our game-specific content.

See below for a description of what the Unreal.ini [EditPackages], [DefaultGame], and [DefaultPlayer] settings mean.

Licensee programmers: Replacing UnrealI.u with your own game-specific package

The first question is, "How do I create my own game package like your UnrealI.u?"

The easiest way to create a new package is by creating your first new class within UnrealEd. When creating a new game using the Unreal technology, you will need to create a custom "GameInfo" class to define high-level gameplay rules. Here's how:

  1. Run UnrealEd
  2. Bring up the "Classes" browser on the right-hand side of the screen.
  3. Expand the "Info" class.
  4. Right-click the "GameInfo" class.
  5. Pick the "Create new class below GameInfo..." menu option.
  6. Give the new class a name, for example "KlingonsGameInfo" and a package, for example "Klingons".
  7. Press F7 (or use the Script/Compile menu option) to recompile the new script.
  8. Save your package's .u binary file by hitting the "Save" button in the class browser and selecting your package.
  9. At the bottom of the class browser, hit the "Export" button to export all classes which you have modified. This generates *.uc files in a directory corresponding to your package. For example, if you just created a class named "KlingonsGameInfo" in a package called "Klingons", UnrealEd will generate the file "\Unreal\Klingons\KlingonGameInfo.uc". The .uc files are pure text versions of your scripts, which can later be cleanly rebuilt.

The next question is, "How do I have my new package used in the editor and during gameplay?" The Unreal.ini file defines many of these project-specific settings you will want to modify for your title:

  • The [EditPackages] section lists the class packages (.u files) to load for editing when UnrealEd is run. You will generally want to remove UnrealI from the list, and add your package(s) to the list, so that your level designers can see all of your content from within UnrealEd.
  • The [DefaultGame] section says which GameInfo-derived class is responsible for moderating gameplay. The GameInfo class (see \Unreal\Engine\GameInfo.uc) makes many high-level gameplay decisions in single-player and network play, i.e. it implements the game rules. For the baseline game, use Engine.GameInfo. To customize the game rules, you must create a subclass of GameInfo.
  • The [DefaultPlayer] section says which PlayerPawn-derived class should be spawned to represent the player in the game. For the baseline game, use Engine.PlayerPawn. To customize the player controls, mesh, etc., create a subclass of PlayerPawn.

Licensee programmers: Working with classes and packages in UnrealEd

The most important thing you need to realize while working with classes is that each class may be stored redundently in two separate places:

  • A binary copy of the class is stored in its package's .u file in the \Unreal\System directory. This binary copy of the class includes all objects referenced by the class. For example, the Skaarj class in the UnrealI package is stored in the file \Unreal\System\UnrealI.u. This binary version includes the Skaarj's mesh and all of the monster's sound effects. The binary copy of the class must be saved by using the "Save" button in the class browser. However, the binary file will break whenever the .u file format changes, which will happen several times prior to the release of Unreal.
  • For licensee programmers who have the entire Unreal C++ and UnrealScript codebase in standalone form, a text copy of the class is stored in one .uc file. For example, the text version of the Skaarj class is stored in \Unreal\UnrealI\Classes\Skaarj.uc. You can save these text files with the "Export" button in the class browser. The .uc file is a text file, so it doesn't contain any binary data. Rather, it contains UnrealScript "#exec" commands to import all ancillary objects like meshes, sound effects, and textures, when you perform a clean rebuild.

There are two ways you can create and edit UnrealScript classes:

  • You create new classes in UnrealEd by right-clicking on an existing class and subclassing it (by choosing the "Create new class below..." menu option), and then use the built-in script editor and compiler. To edit an existing class, just double-click on it. Use Script/Compile (or F7) to recompile your script.
  • You can create new classes from outside UnrealEd by creating a new .uc file in the package's directory. For example, to add a new class named "Timster" to the "UnrealI" package, create a new file called "\Unreal\UnrealI\Classes\Timster.uc". This way, you can use your favorite stand-alone editing tool, such as the text editor built into Visual C++, to edit your script. However, when you manually work with .uc files, you must cleanly rebuild your package in order to regenerate the binary .u file which UnrealEd requires.

To summarize:

  • You can create new classes in UnrealEd using the built-in editor, or you can work directly with the .uc files using your favorite stand-alone editor.
  • There is one text .uc for each class. Think of this as your source code.
  • There is one binary .u file for each package. Think of this as your object code.

Programmers: Cleanly rebuilding your packages from the command line

You can rebuild individual .u files, or all of the .u files, from the command line as follows:

  1. Delete the .u file(s) which you want to rebuild. For example, type "del \Unreal\System\*.u".
  2. Type "Unreal -make" to run Unreal and rebuild the .u files.
  3. Now, Unreal will go through all of the packages listed in the Unreal.ini [EditPackages] section, and rebuild any packages whose .u files are missing.

When Unreal rebuilds a package, it switches into the \Unreal\packagename\Classes directory (for example, if you're rebuilding the Engine package, it switches into \Unreal\Engine\Classes), and it imports all of the *.uc files it finds there.

The .uc files are text files containing UnrealScript code. There is one .uc file for each class. The .uc filename must correspond to the class name. For example, the PlayerPawn class must reside in the file "PlayerPawn.uc".

The .uc files may contain special UnrealEd commands which begin with the keyword "#exec". These "#exec" commands import various objects as the script is compiled. For example, #exec commands exist to import textures, sounds, meshes, and music. The "#exec" commands are not currently documented; you will need to see the example .uc files in the UnrealI package for examples of usage.

Rebuilding certain packages, such as the Engine package and the UnrealI package, requires that you have the source artwork, sounds, and meshes, which are available on the UnEdit ftp site as a separate download. The source data is not included in the regular source distribution because of its huge size. The source artwork can be extracted with WinZip into the various subdirectories of the Unreal\Engine\ and \Unreal\UnrealI\ directories (for example, the engine sounds go into \Unreal\Engine\Sounds).

When cleanly rebuilding, any UnrealScript compiler errors cause the rebuild to halt, and an appropriate error message is displayed on the screen.

To summarize:

  • Using "Unreal -make" cleanly rebuilds any missing .u files.
  • All .uc files (UnrealScript class definitions) are imported and recompiled.
  • The .uc files may contain "#exec" commands to import ancillary content.
  • The end result is that a new .u file is generated for each missing package.

Package file attributes: .upkg Files

When Unreal rebuilds your package using "Unreal -make", it tries to load a text PackageName.upkg definition file from the same \Unreal\PackageName\Classes directory. If not found, the default package options are used. A sample package definition file looks like this:

[Flags]
AllowDownload=False
ClientOptional=False
ServerSideOnly=True

The options that appear in a package definition file are:

  • AllowDownload: Whether you want players to be able to download this file when they enter a server. This should be enabled for user-created modifications, and disabled for game publisher distribution (so that people aren't able to download retail files freely).
  • ClientOptional: Whether the package is optional on the client side. Not currently supported; may be supported in the future for things like player skins.
  • ServerSideOnly: Says the package should only be loaded on the server side, and is not necessary for clients. For example, the IpDrv.u package is tagged as ServerSideOnly, because it contains classes like the server-uplink which only need to run on the server, and will be frequently updated.

Licensee programmers: Generating C++ header files which mirror your UnrealScript classes

If you create any intrinsic UnrealScript classes, or if you need to access any UnrealScript classes from C++ code, then you can have Unreal generate a C++ header file which mirrors the classes you've defined in UnrealScript.

For example, the Actor class any many of its child classes are defined by scripts in the Engine package (such as \Unreal\Engine\Classes\Actor.uc). The C++ code in the engine often needs to access objects in the Actor class. Early in development, we manually created C++ definitions which mirrored all of the UnrealScript classes. This process became tedious and error-prone as the number of classes increased. So, we added an option to Unreal to automatically generate a C++ header file, based on your UnrealScript definitions.

For an example of an automatically-generated C++ header file, check out "\Unreal\Engine\Inc\EngineClasses.h". This file was not written by a human. Unreal generated it.

To automatically generate a C++ header for a package, do the following:

  1. Delete the package's .u file. For example, type "del \Unreal\System\Engine.u".
  2. Run Unreal with the following parameters: "Unreal -make -h".
  3. Unreal will create a new file for you, called "\Unreal\Engine\Inc\EngineClasses.h".
  4. Now recompile the C++ source code.

Because there are many ways which UnrealScript and C++ can share information back and forth, the automatically-generated header file (for example EngineClasses.h) contains a variety of definitions:

  • The enumerations defined in the package.
  • C++ class definitions for all the intrinsic classes defined in the package. Note that non-intrinsic classes are not exported to the header file, because you can only access intrinsic classes from C++. (Note: this does not in any way limit what you can do in UnrealScript vs. C++).
  • For each class, C++ class member functions for all intrinsic functions defined in the class.
  • For each class, a C++ "#include" statement if a class-specific header file exists (for example, the Unreal generated C++ definition of the Actor class contains the #include "AActor.h" statement because the file \Unreal\Engine\Inc\AActor.h exists.

For a more concrete example, carefully examine the UnrealScript file "\Unreal\Engine\Classes\TcpLink.uc" and the following definitions in the file \Unreal\Engine\Inc\EngineClasses.h": enum ETcpLinkState, enum ETcpMode, and class ATcpLink. This provides an example of a fairly isolated UnrealScript class which defines several enumerations and intrinsic functions.

Finally, to avoid a chicken-and-egg scenario, you should create new classes in the following order: first create a class in UnrealScript, then generate the C++ header, then recompile the engine code (adding in the IMPLEMENT_CLASS macro for any new intrinsic classes you've added).

To summarize the important points here:

  • You created a new class in UnrealScript.
  • You needed to access that new class from C++.
  • You used the "Unreal -make -h" command to automatically generate a C++ header file defining the package's classes.

Programmers: Package related problems to avoid

  • Don't remove objects from packages which other people are relying on. For example, say level designers are using a texture package like SkyCity.utx which contains a texture named "SkyWall2" which they're using in many of their levels. If you go through and remove that texture from the .utx file, then the level designers won't be able to load their levels successfully. Rather they will get an error message along the lines of "Texture SkyWall2 was not found in package SkyCity.utx".
  • Avoid package filename collisions. Packages are identified by their base (extension-less) names, so you should node create a texture package named "Fred.utx" and a level named "Fred.unr". The base filename of each package must be unique.
  • Avoid circular package dependencies in .u files. For example, if you create two packages, "MyPackage" and "YourPackage" which both contain UnrealScript classes that refer to the other package, it will be impossible to cleanly rebuild both packages. During the clean rebuild process, packages are imported in the order they are specified in the Unreal.ini [EditPackages] section, and each package may only be dependent on the packages listed before it.
  • If you delete an UnrealScript, you must manually remove the .uc file corresponding to it. When you do a clean rebuild, Unreal imports all of the *.uc files in each package's directory.

Licensee programmers: Putting .uc script files under source control with SourceSafe

For programmers who like to keep their work archived under Microsoft Visual SourceSafe, here are some tips. We use SourceSafe internally for our development, though it is purely optional -- nothing in the Unreal source code assumes that you have SourceSafe:

  • Put all of your .uc files under source control (.uc files are text files containing the text of the UnrealScript code).
  • If someone removes a .uc file from source control, be sure to delete the corresponding .uc file on disk.
  • In the UnrealEd class browser, the "Export" button exports all scripts which you've modified. If you try to export a script which you haven't checked out of SourceSafe, you will get a (safe, non-fatal) warning message that the .uc file is write-protected. If that happens, just check the .uc file out of SourceSafe and hit the "Export" button again.

Programmers: Adding/Removing variables in UnrealScript classes can be dangerous

When you add or remove variables in an UnrealScript class, that changes the binary layout of objects belonging to that class. For example, if you have a script that contains some variable declarations like this:

class TestClass expands Actor;

var int i, j;
var texture t;

And you remove one of the variables like this:

class TestClass expands Actor;
var int i;
var texture t;

Then any objects in memory belonging to TestClass will become corrupted as soon as you recompile the script. The solution is to only add or remove variables from a script in an empty level. However, empty levels contain an actor belonging to the LevelInfo class, as well as one or more Camera actors, so it's never safe to add or remove variables from any of the following classes in UnrealEd: Actor, Info, LevelInfo, Camera, PlayerPawn, Pawn. To work with these files, edit their .uc files on-disk, and do a clean rebuild.

Also, bear in mind that Unreal makes heavy use of the Actor, Pawn, PlayerPawn, LevelInfo, and other intrinsic classes in C++ code. So, adding and removing variables to any intrinsic classes will cause the C++ code and UnrealScript code to disagree about the binary layout of classes. Whenever you change an intrinsic class, the safe thing to do is a clean rebuild with the "Unreal -make -h" option to generate new C++ header files for your classes, then recompile the Unreal C++ source.

Programmers: The package file format

Abandon all hope ye who try to parse this file format.

The Unreal package file format is only useful to people who want to write external utilities that read and write Unreal files. Level designers and UnrealScript programmers don't need to know this info. But, the Unreal package file format is quite complex compared to what Quake, Quake 2, and Jedi Knight utility writers are accustomed to. It's so complex, in fact, that I doubt many utility writers are going to want to deal with it directly. It is complex for several reasons:

  • Unreal files can contain a wide range of objects (there are hundreds of unique classes defined in Unreal), versus perhaps 20-30 for Quake.
  • Unreal objects can contain complex interdependencies: for example, a level package can refer to a texture package, which can refer to a class package, which can contain a class that refers to a sound in a sound package. So, each package file needs to keep track of not only the objects it contains, but also the external objects that it refers to.
  • Unreal objects are expandable by users, so we needed to create a generalized system for serializing (a.k.a. saving and loading) these complex user-defined objects.
  • Unreal objects are scoped within hierarchical packages (much like DOS and Windows files are scoped within a system of hierarchical directories). Therefore, the entire tree structure of the object scope hierarchy must be described within the file.

The coming release of the enhanced version of UnrealEd in 3+ months will include a very modular plug-in interface for creating built-in UnrealEd tools, file importing tools, and file exporting tools, which will operate directly on the engine's C++ data. That release will greatly simplify the task of programmers who want to write Unreal utilities, because it eliminates the need to read and write package files directly. Rather, with the UnrealEd plug-in interface, you will be able to use C++ to create all of your tools and compile them into DLL's. You'll make calls to the Unreal engine to allocate objects, save package files, load package files, etc. with the hairy file-format issues taken care of by the engine.

Data types stored in package files.

  • The "int" type is signed, 4 bytes long, and is stored in Intel byte order.
  • The "float" type is signed, IEEE standard, 4 bytes long, and stored in Intel byte order.
  • The "string" type is stored as a bunch of characters (one nonzero byte each) terminated by a zero byte.
  • The "FCompactIndex type" corresponds to a 32-bit signed value but are stored in a compacted format. See below for a description.
  • The "FGuid" type corresponds to a set of four consecutive int's defining a globally unique identifier.

Object and Name flags.

Each object and name stored in a package file can contain any combination of the following bitflags:

  • RF_LoadForClient (0x00010000): Must be loaded for game client.
  • RF_LoadForServer (0x00020000): Must be loaded for game server.
  • RF_LoadForEdit (0x00040000): Must be loaded for editor.
  • RF_Public (0x00000004): Object may be imported by other package files.
  • RF_Standalone (0x00080000): Keep object around (don't garbage collect) for editor even if unreferenced.
  • RF_Intrinsic (0x04000000): Class or name is defined in C++ code and must be bound at load-time.
  • RF_SourceModified (0x00000020): The external data source corresponding to this object has been modified.
  • RF_Transactional (0x00000001): Object must be tracked in the editor by the Undo/Redo tracking system.
  • RF_HasStack (0x02000000): This object has an execution stack allocated and is ready to execute UnrealScript code.

Any other bitflags stored in package files are irrelevent, should be set to zero when saving a package file, and should be ignored when loading a package file.

Compact Indices.

Compact indices exist so that small numbers can be stored efficiently. An index named "Index" is stored as a series of 1-5 consecutive bytes with the following C++ code. Basically, the "Ar << B0" type code serializes the byte stored in the variable B0. Serialize can mean read or write, depending on the internal implementation of the archive object Ar.

//
// FCompactIndex serializer.
//
FArchive& operator<<( FArchive& Ar, FCompactIndex& I )
{
           INT Original = I.Value;
    DWORD V = Abs(I.Value);
           BYTE B0 = ((I.Value>=0) ? 0 : 0x80) + ((V < 0x40) ? V : ((V & 0x3f)+0x40));
        I.Value = 0;
        Ar << B0;
        if( B0 & 0x40 )
        {
            V >>= 6;
            BYTE B1 = (V < 0x80) ? V : ((V & 0x7f)+0x80);
            Ar << B1;
            if( B1 & 0x80 )
            {
                V >>= 7;
                BYTE B2 = (V < 0x80) ? V : ((V & 0x7f)+0x80);
                Ar << B2;
                if( B2 & 0x80 )
                {
                    V >>= 7;
                    BYTE B3 = (V < 0x80) ? V : ((V & 0x7f)+0x80);
                    Ar << B3;
                    if( B3 & 0x80 )
                    {
                        V >>= 7;
                        BYTE B4 = V;
                        Ar << B4;
                        I.Value = B4;
                    }
                    I.Value = (I.Value << 7) + (B3 & 0x7f);
                }
                I.Value = (I.Value << 7) + (B2 & 0x7f);
            }
            I.Value = (I.Value << 7) + (B1 & 0x7f);
        }
        I.Value = (I.Value << 6) + (B0 & 0x3f);
        if( B0 & 0x80 )
            I.Value = -I.Value;
        if( Ar.IsSaving() && I.Value!=Original )
            appErrorf("Mismatch: %08X %08X",I.Value,Original);
    }
    return Ar;
}

Names

Names are stored a compact indices with values >= 0 which index into the file's name table.

Objects References.

Objects are stored as compact indices with values defined as follows:

  • If Index==0: The object is NULL (known as NULL in C++, None in UnrealScript).
  • If Index<0: Refers to the (-Index-1)th object in this file's import table.
  • If Index>0: Refers to the (Index-1)th object in this file's export table.

The Package file header.

  • int Tag: Always 0x9E2A83C1 (see PACKAGE_FILE_TAG in UnObjVer.h).
  • int FileVersion: Version of the engine which saved the file. Currently 61. Utilities should only operate on files with this exact version number, because only the file header is guaranteed not to change in future versions...anything else could change (See PACKAGE_FILE_VERSION in UnObjVer.h).
  • int PackageFlags: Bitflags describing the package:
    • PKG_AllowDownload (0x0001): The package is allowed to be downloaded to clients freely.
    • PKG_ClientOptional (0x0002): All objects in the package are optional (i.e. skins, textures) and it's up to the client whether he wants to download them or not. Not yet implemented; currently ignored.
    • PKG_ServerSideOnly (0x0004): This package is only needed on the server side, and the client shouldn't be informed of its presence. This is used with packages like IpDrv so that it can be updated frequently on the server side without requiring downloading stuff to the client.
  • int NameCount: Number of names stored in the name table. Always >= 0.
  • int NameOffset: Offset into the file of the name table, in bytes. 0 designates the first byte of the file, of course.
  • int ExportCount: Number of exported objects in the export table. Always >= 0.
  • int ExportOffset: Offset into the file of the export table.
  • int ImportCount: Number of imported objects in the import table. Always >= 0.
  • int ImportOffset: Offset into the file of the import table.
  • int HeritageCount: Number of GUID's stored in the package's heritage table. Always >= 1.
  • int HeritageOffset: Offset into the file of the heritage GUID table.

The following tables reside in the file at the offset specified by the header. If a table contains zero entries (as specified in the header), the offset value is meaningless and should be ignored.

Name table.

Contains a list of human-readable Unreal names (which correspond to the UnrealScript "name" datatype and the C++ "FName" data type). Each name is stored consecutively in the following format:

  • string NameString: String representation of the name, up to NAME_SIZE characters (currently 64, may increase with future versions).
  • int NameFlags: Internal flags describing the name. See "Object and Name Flags" above.

Export table.

Contains a list of objects contained in (a.k.a. "exported by") this file. Similar to a Windows DLL's export table.

  • object reference ClassIndex: Points to the class object describing the class of this object.
  • int PackageIndex: Points to the package object describing the package this object resides in.
  • object reference SuperIndex: If this is a field (a struct, class, property, or another field subclass): Points to the superfield object of the field.
  • FName ObjectName: This object's name.
  • int ObjectFlags: Flags.
  • int SerialSize: Size (in bytes) of the object's serialized data stored in this file.
  • if SerialSize>=0, int SerialOffset: Offset into this file of the start of the object's serialized data.

Import table.

Contains a list of objects in other packages which this packages refers to. Similar to a Windows DLL's import table.

  • name ClassPackage: The name of the package which this object's class object resides in.
  • name ClassName: The name of this object's class.
  • int PackageIndex: The index of the package this object resides in.
  • FName ObjectName: The name of this object.

Heritage GUID table.

Contains a list of GUID's which this package is compatible with. In the current version of Unreal, this table always contains exactly one GUID, because the backwards-compatible package management code has not yet been written. In the future, it may contain more than one GUID. Each entry contains:

  • A GUID (4 consecutive int's).

Serialize object format.

Extremely complex. Different for each class. Hard to read. Not yet documented.


UnrealEd Quick Reference

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Level Designers
UnrealEd undergoes rapid changes so this document may not be up-to-date.
Last Updated: 01/25/02

Having problems starting UnrealEd?

If you're having problems starting UnrealEd, please install the UnrealEd Fix 4 -- this eliminates the "Runtime Error 50003" messages and some other frequently-reported problems starting UnrealEd. Try it!

Particle Systems

  1. Here's how to create particle systems in Unreal.
  2. Create and animate a mesh. The process for creating particle system meshes is identical to that for regular creature/weapon meshes (create triangle meshes, make sure they're scaled properly, import them into Unreal using the normal procedure). Texture coordinates and textures don't matter, however. When Unreal renders a particle system, it will draw a scaled sprite at each VERTEX in your animated mesh. So, the mesh triangles don't matter at all for rendering, just the vertices. Since particles are based on mesh vertices, particles cannot be created or destroyed during an animation.
  3. Assign the mesh to an actor class. Set the following default properties:
    • Style = How you want the particles to be rendered:
      STY_None (Invisible)
      STY_Normal (Normal solid particles)
      STY_Masked (Masked particles)
      STY_Translucent (Translucent particles)
      STY_Modulated (Modulated particles, i.e. dark smoke)
    • Texture = The texture map you want rendered for the particle sprites. They're all rendered with the same exact texture!
    • Mesh = The mesh to use for generating particle vertices.
    • DrawScale = How much to scale the particle sprites by.
    • bParticles = True.

See the DispersionAmmo.uc script and its corresponding little particle effect Spark3.uc for an example of a cool particle system. It's the projectile for Unreal's default weapon. Note how Spark3t uses STY_Translucent, and then fades the particles from full brightness down to nothingness by modifying ScaleGlow and AmbientGlow in the Tick() function.

Suggestions for making maps run faster

Here are some fairly straightforward tricks that can be implemented in existing maps. These are worthwhile enough that I recommend going back and applying them to existing maps, in the worst-performance areas where you need a speed boost. The areas that are noticeably slow are the large outdoor areas where you see buildings from the outside, and areas which use a lot of dynamic light.

  • When you have a huge outdoor area, have as few far-away meshes in view as possible. Type "STAT MESH" and look at the "MESHCOUNT=xxx" number to see how many meshes are in view. About 50% of the CPU time required to draw a mesh is irrespective of its size, so if you have a gun lying on the ground a mile away, but it's visible, even though it might only take up 1 pixel on the screen, it takes several milliseconds for the engine to perform lighting, transformation, and teeny polygon rendering on it. For example, in walking along the ridge in Bluff, the MESHCOUNT is 6, though I was only aware of one mesh (the Nali). It turns out that there's a transparent window, and two meshes visible through the transparent window, and three meshes somewhere else (not sure where).
  • In the huge levels that combine indoors and outdoors, like Bluff, where you want to have transparent windows that players can see out of, use this one-way transparency trick: Add a semisolid cube brush for the window; make the inside face transparent and one-sided; and make the outside face non-transparent and one-sided. This way, players inside can see out, but players outside can't see in. This noticeably speeds up maps when the player is on the outside, looking in.
  • If you have a lot of dynamic lights in an area, and you don't mind extremely fuzzy (low detail) shadows, use the "super low shadow detail trick": If you select both "low shadow detail" and "high shadow detail" on a surface together, the engine uses a special "super low shadow detail" mode which is 4X faster for dynamic lighting. Since this makes the shadows extremely fuzzy (which looks weird sometimes), this isn't a good trick to use all over the place -- it's just for the areas where you want to have a LOT of dynamic light, or dynamic light in huge outdoors areas.

Stupid UnrealEd Tricks

These are things people needed but I didn't have time to create proper user interfaces for:

To align textures as floors (like for the ground in Pancho's hubs) AND scale them up, do this:

1. Select the polygons.
2. Do the normal "align as floor" thing.
3. In the log window, type: POLY TEXSCALE RELATIVE UU=2.0 VV=2.0

The above command scales them up by a factor of 2.0. You can scale them up or down by different amounts by plugging in different numbers, for example: POLY TEXSCALE RELATIVE U=0.5 V=0.5

If you have a super-huge outdoor area and you want even lower shadow detail than normal, you can check both the "Low Shadow Detail" and the "High Shadow Detail" options. UnrealEd recognizes this as a special combination that means "Superduperultralow shadow detail".

Special mouse clicking combinations

  • A + right mouse click: Add actor there.
  • L + right mouse click: Add light there.

Shortcut keys

  • Delete: Delete selected actors.
  • 1, 2, 3: Slow, medium, and fast movement speed.
  • F1: Help.
  • F4: Actor properties.
  • F5: Surface properties.
  • F6: Level properties.
  • F7: Compile changed scripts.
  • F8: Rebuilder.
  • B: Toggle brush visibility in the current viewport.
  • H: Toggle actor visibility in the current viewport.
  • P: Toggle player controls or realtime update of the viewport.
  • Shift-A: Select all actors.
  • Shift-B: Select all surfaces belonging to the selected surfaces' brushes.
  • Shift-C: Select adjacent coplanar polygons.
  • Shift-D: Duplicate selected actors.
  • Shift-F: Select adjacent floors.
  • Shift-G: Select surfaces belonging to the selected surfaces' groups.
  • Shift-I: Select surfaces with items matching the selected surfaces' items.
  • Shift-J: Select all adjacent surfaces(flood-fill).
  • Shift-L: Look ahead in the current viewport (no pitch or roll).
  • Shift-M: Memorize selected surfaces.
  • Shift-N: Select none.
  • Shift-O: Select surfaces from intersection of selected surfaces and memory.
  • Shift-P: Select all surfaces.
  • Shift-Q: Reverse the set of selected surfaces.
  • Shift-R: Recall memorized surface selection.
  • Shift-T: Select all surfaces which use the current texture.
  • Shift-U: Select union of selected surfaces and memorized surfaces.
  • Shift-W: Select adjacent wall surfaces (flood-fill).
  • Shift-X: Select exclusive or of selected surfaces and memorized surfaces.
  • Shift-Y: Select adjacent slanted surfaces.
  • Shift-Z: Select none.
  • Ctrl-A: Add brush to world.
  • Ctrl-B: Load brush.
  • Ctrl-C: Copy.
  • Ctrl-D: Deintersect brush with world.
  • Ctrl-E: Save as.
  • Ctrl-L: Save level.
  • Ctrl-O: Load level.
  • Ctrl-P: Play level.
  • Ctrl-N: Intersect brush with world.
  • Ctrl-R: Redo.
  • Ctrl-S: Subtract brush from world.
  • Ctrl-V: Paste.
  • Ctrl-W: Duplicate.
  • Ctrl-X: Cut.
  • Ctrl-Z: Undo.

End


Unreal Textures

Tim Sweeney
Epic MegaGames, Inc.
tim@epicgames.com
http://www.epicgames.com/

Audience: Artists, level designers.
Last Updated: 01/25/02

Texture dimensions

Unreal texture dimensions may be any powers of two from 1 to 1024. Textures need not be square. For example, many of the textures in Unreal 1 are 128x128, 256x128, and 256x256. Unreal's software rendering code supports textures of any size from 1x1 up to 1024x1024.

Unreal's 3D hardware rendering code gracefully handles textures of all sizes from 1x1 up to 1024x1024, though the actual rendered texture resolution is limited to texture sizes which the hardware supports. All current hardware is limited to 256x256 textures. For example, when you see a 1024x1024 texture on 3dfx hardware, Unreal substitutes a lower resolution (256x256) version of the texture. The texture is scaled up properly, so that the only noticeable artefact is blurring of the texture.

Because most current 3D hardware only supports textures up to 256x256, we generally don't use higher resolution textures in our game.

Creating and importing textures

Unreal textures are palettized, 256-color textures. Each texture in Unreal may have its own palette. The result is that you can achieve a lot of color variety by using textures with different palettes, while benefitting from the space savings of 8-bit textures.

The Unreal team creates textures in Fractal Painter and Photoshop, always working with the source art in 24-bit color. When a texture is complete, it is converted into a 256-color, palettized .pcx or .bmp file and imported into UnrealEd. To import a texture into UnrealEd, go into the texture browser (on the right side of the screen), and click on the "Import" button. When importing a texture, you can specify its name, the texture group it should appear in, and the package (.utx file) it should be saved in.

Unreal a texture mapping feature called "masking", where color zero is treated as if it were transparent. We use this for textures like vines, grating, and sprites. To create a masked texture, you will need to use a 256-color paint program to edit your image and apply color zero to the transparent portions of the texture. Then, import the texture and click on the "Masked" checkbox in the texture importing dialog. If you don't click on the "Masked" checkbox, the texture's mipmaps will not be properly masked.

When you import a texture, UnrealEd will automatically create mipmaps for the texture (mipmaps are lower resolution versions of the texture, used for antialiasing far-away polygons).

When you import two textures which use the same palette, UnrealEd makes note of this fact and takes advantage of it for optimization. In hardware rendering, the frame rate is partly dependent on the number of palettes visible in a scene, so there is a performance advantage to forcing textures to have the same palette. Programs like Image Alchemy can convert groups of 24-bit color images to 8-bit and force a common palette.

Graphics tools we use and recommend

  • Fractal Painter: For realistic painting of textures.
  • Photoshop: For realistic painting of textures and retouching of digitized textures.
  • Deluxe Paint: For creating masked textures, and for creating custom palettes.
  • Image Alchemy: For batch converting 24-bit color images to 256-color images.

Editing texture properties

To edit a texture's properties in UnrealEd, right-click on the texture in the texture browser (on the right side of the screen), and click on the "Properties" menu item. Here you can customize many properties of a texture. The properties which are not documented here are reserved for future use, and not yet supported.

Animating textures

The easiest way to create a sequence of animating textures is to import a bunch of textures with names that end in _A## (where ## is the number of the animation frame, starting at zero). For example, to create a four-texture animation sequence, import four files named:

  • MyAnim_A00.bmp
  • MyAnim_A01.bmp
  • MyAnim_A02.bmp
  • MyAnim_A03.bmp

When you import a texture into UnrealEd, it looks for _A## in the name and then sets up the texture for animation.

When you import animating textures into UnrealEd, the editor shows all of the individual frames of animation. However, you should always use the first one (the one with the name ending in A00) when setting the texture's properties and adjusting its frame rate. The following useful texture properties are related to animation:

  • AnimNext: The next texture in the animation sequence, or None to indicate that the sequence should proceed back to the first texture.
  • PrimeCount: For procedural animating textures, the texture internally animates itself PrimeCount times before it's first rendered. Use this to avoid algorithmic fire billowing up the first time it comes into view.
  • MinFrameRate: The minimum frame rate for the animation. The texture will always animate this fast, or faster (0 indicates that the texture should animate at the rendering frame rate).
  • MaxFrameRate: The maximum frame rate for the animation. The texture will always animate this fast, or slower. If you set this equal to MinFrameRate, the texture animation rate will never vary.

For texture animation, we support two animation rates (MinFrameRate and MaxFrameRate) to prevent "animation aliasing": the annoying artefacts you see when a texture animates through frames at a variable rate, such as "1 2 2 3 4 4 5". When the rendering frame rate is between MinFrameRate and MaxFrameRate, the texture will always animate smoothly, i.e. "1 2 3 4 5".

Detail textures and Macrotextures

A texture may optionally have a Detail texture and a Macrotexture associated with it. A detail texture is a very small, fine pattern which is faded in as you approach a surface, for example wood grain, or imperfections in stone. A Macrotexture is a large, scaled-up texture which is overlaid onto surface. For example, Macrotextures can be used to add large-scale detail to textures in outdoor spaces to avoid an overly "tiled" look.

Detail textures and Macrotextures only are visible on 3d hardware. For performance reasons, they are ignored in the software rendering code.

When you bring up the "texture properties" editor, you can associate a detail texture and a macrotexture with a given texture.

When you import a detail texture, you need to set its Scale value to a small number (typically 0.25) to specify its scaling relative to whatever texture it applies to. Macrotextures need to have their Scale value set to a large number (typically 8) to specify its scaling relative to the surface it's applied on.

It is valid to use procedural textures as macrotextures, microtextures, or both.

Detail textures and macrotextures modulate (multiply) the surface they're applied to. By modulating, they have the ability to scale the surface's brightness up or down. Colors with RGB brightness values from 0-127 darken the surface; 128 has no effect; and 129-255 brighten the surface. Therefore, when drawing microtextures and macrotextures, it is important that you design them with their brightnesses in the proper range so they affect surfaces naturally. If a detail texture's average brightness deviates too far from 128, then surfaces will appear to brighten or darken as you approach them.

Procedural textures

To create a new procedural texture, click on the "New" button in the texture browser and select a type of texture to create, for example "FireTexture" or "WaveTexture". Procedural textures are animated algorithmically so they have infinite, non-repeating animation. They also have the advantage of taking up very little disk space (on the order of 4K) and they only occupy as much memory as a single, non-animating texture of the same size. The procedural texture types and their options are documented elsewhere.

Texture .utx files

Unreal saves texture packages into .utx files. A .utx file contains all of the textures (one or more) in a particular package. The .utx file format contains the raw texture bitmaps as well as mipmaps, texture properties, and palettes. A game created with the Unreal engine will typically ship with many .utx files (one for each texture package).


UnrealScript Language Reference

Tim Sweeney
Epic MegaGames, Inc.
tim@epicgames.com
http://www.epicgames.com/

Last Updated: 01/25/02

Introduction

Purpose of this document

This is a technical document describing the UnrealScript language. It’s not a tutorial, nor does it provide detailed examples of useful UnrealScript code. For examples of UnrealScript prior to release of Unreal, the reader is referred to the source code to the Unreal scripts, which provides tens of thousands of lines of working UnrealScript code which solves many problems such as AI, movement, inventory, and triggers. A good way to get started is by printing out the "Actor", "Object", "Pawn", "Inventory", and "Weapon" scripts.

This document assumes that the reader has a working knowledge of C/C++, is familiar with object-oriented programming, has played Unreal and has used the UnrealEd editing environment.

For programmers who are new to OOP, I highly recommend going to Amazon.com or a bookstore and buying an introductory book on Java programming. Java is very similar to UnrealScript, and is an excellent language to learn about due to its clean and simple approach.

Design goals of UnrealScript

UnrealScript was created to provide the development team and the third-party Unreal developers with a powerful, built-in programming language that maps naturally onto the needs and nuances of game programming.

The major design goals of UnrealScript are:

  • To support the major concepts of time, state, properties, and networking which traditional programming languages don’t address. This greatly simplifies UnrealScript code. The major complication in C/C++ based AI and game logic programming lies in dealing with events that take a certain amount of game time to complete, and with events which are dependent on aspects of the object’s state. In C/C++, this results in spaghetti-code that is hard to write, comprehend, maintain, and debug. UnrealScript includes native support for time, state, and network replication which greatly simplify game programming.
  • To provide Java-style programming simplicity, object-orientation, and compile-time error checking. Much as Java brings a clean programming platform to Web programmers, UnrealScript provides an equally clean, simple, and robust programming language to 3D gaming. The major programming concepts which UnrealScript derives from Java are: a pointerless environment with automatic garbage collection; a simple single-inheretance class graph; strong compile-time type checking; a safe client-side execution "sandbox"; and the familiar look and feel of C/C++/Java code.
  • To enable rich, high level programming in terms of game objects and interactions rather than bits and pixels. Where design tradeoffs had to be made in UnrealScript, I sacrificed execution speed for development simplicity and power. After all, the low-level, performance-critical code in Unreal is written in C/C++ where the performance gain outweighs the added complexity. UnrealScript operates at a level above that, at the object and interaction level, rather than the bits and pixels level.

During the early development of UnrealScript, several major different programming paradigms were explored and discarded before arriving at the current incarnation. First, I researched using the Sun and Microsoft Java VM’s for Windows as the basis of Unreal’s scripting language. It turned out that Java offered no programming benefits over C/C++ in the Unreal context, added frustraging restrictions due to the lack of needed language features (such as operator overloading), and turned out to be unfathomably slow due to both the overhead of the VM task switch and the inefficiencies of the Java garbage collector in the case of a large object graph. Second, I based an early implementation of UnrealScript on a Visual Basic variant, which worked fine, but was less friendly to programmers accustomed to C/C++. The final decision to base UnrealScript on a C++/Java variant was based on the desire to map game-specific concepts onto the language definition itself, and the need for speed and familiarity. This turned out to be a good decision, as it has greatly simplified many aspects of the Unreal codebase.

Example program structure

This example illustrates a typical, simple UnrealScript class, and it highlights the syntax and features of UnrealScript. Note that this code may differ from that which appears in the current Unreal source, as this documentation is not synced with the code.

//=============================================================================
// TriggerLight.
// A lightsource which can be triggered on or off.
//=============================================================================
class TriggerLight expands Light;

//-----------------------------------------------------------------------------
// Variables.

var() float ChangeTime; // Time light takes to change from on to off.
var() bool bInitiallyOn; // Whether it's initially on.
var() bool bDelayFullOn; // Delay then go full-on.

var ELightType InitialType; // Initial type of light.
var float InitialBrightness; // Initial brightness.
var float Alpha, Direction;
var actor Trigger;

//-----------------------------------------------------------------------------
// Engine functions.

// Called at start of gameplay.
function BeginPlay()
{
    // Remember initial light type and set new one.
    Disable( 'Tick' );
    InitialType = LightType;
    InitialBrightness = LightBrightness;
    if( bInitiallyOn )
    {
        Alpha = 1.0;
        Direction = 1.0;
    }
    else
    {
        LightType = LT_None;
        Alpha = 0.0;
        Direction = -1.0;
    }
}

// Called whenever time passes.
function Tick( float DeltaTime )
{
    LightType = InitialType;
    Alpha += Direction * DeltaTime / ChangeTime;
    if( Alpha > 1.0 )
    {
        Alpha = 1.0;
        Disable( 'Tick' );
        if( Trigger != None )
            Trigger.ResetTrigger();
    }
    else if( Alpha < 0.0 )
    {
        Alpha = 0.0;
        Disable( 'Tick' );
        LightType = LT_None;
        if( Trigger != None )
            Trigger.ResetTrigger();
    }
    if( !bDelayFullOn )
        LightBrightness = Alpha * InitialBrightness;
    else if( (Direction>0 && Alpha!=1) || Alpha==0 )
        LightBrightness = 0;
    else
        LightBrightness = InitialBrightness;
}

//-----------------------------------------------------------------------------
// Public states.

// Trigger turns the light on.
state() TriggerTurnsOn
{
    function Trigger( actor Other, pawn EventInstigator )
    {
        Trigger = None;
        Direction = 1.0;
        Enable( 'Tick' );
    }
}

// Trigger turns the light off.
state() TriggerTurnsOff
{
    function Trigger( actor Other, pawn EventInstigator )
    {
        Trigger = None;
        Direction = -1.0;
        Enable( 'Tick' );
    }
}

// Trigger toggles the light.
state() TriggerToggle
{
    function Trigger( actor Other, pawn EventInstigator )
    {
        log("Toggle");
        Trigger = Other;
        Direction *= -1;
        Enable( 'Tick' );
    }
}

// Trigger controls the light.
state() TriggerControl
{
    function Trigger( actor Other, pawn EventInstigator )
    {
        Trigger = Other;
        if( bInitiallyOn ) Direction = -1.0;
        else Direction = 1.0;
        Enable( 'Tick' );
    }
    function UnTrigger( actor Other, pawn EventInstigator )
    {
        Trigger = Other;
        if( bInitiallyOn ) Direction = 1.0;
        else Direction = -1.0;
        Enable( 'Tick' );
    }
}

The key elements to look at in this script are:

  • The class declaration. Each class "expands" (derives from) one parent class, and each class belongs to a "package", a collection of objects that are distributed together. All functions and variables belong to a class, and are only accessible through an actor that belongs to that class. There are no system-wide global functions or variables.
  • The variable declarations. UnrealScript supports a very diverse set of variable types including most base C/Java types, object references, structs, and arrays. In addition, variables can be made into editable properties which designers can access in UnrealEd without any programming.
  • The functions. Functions can take a list of parameters, and they optionally return a value. Functions can have local variables. Some functions are called by the Unreal engine itself (such as BeginPlay), and some functions are called from other script code elsewhere (such as Trigger).
  • The code. All of the standard C and Java keywords are supported, like "for", "while", "break", "switch", "if", and so on. Braces and semicolons are used in UnrealScript as in C, C++, and Java.
  • Actor and object references. Here you see several cases where a function is called within another object, using an object reference.
  • The "state" keyword. This script defines several "states", which are groupings of functions, variables, and code which are executed only when the actor is in that state.
  • Note that all keywords, variable names, functions, and object names in UnrealScript are case-insensitive. To UnrealScript, "Demon", "demON", and "demon" are the same thing.

The Unreal Virtual Machine

The Unreal Virtual Machine consists of several components: The server, the client, the rendering engine, and the engine support code.

The Unreal server controls all gameplay and interaction between players and actors. In a single-player game, both the Unreal client and the Unreal server are run on the same machine; in an Internet game, there is a dedicated server running on one machine; all players connect to this machine and are clients.

All gameplay takes place inside a "level", a self-contained environment containing geometry and actors. Though UnrealServer may be capable of running more than one level simultaneously, each level operates independently, and are shielded from each other: actors cannot travel between levels, and actors on one level cannot communicate with actors on another level.

Each actor in a map can either be under player control (there can be many players in a network game) or under script control. When an actor is under script control, its script completely defines how the actor moves and interacts with other actors.

With all of those actors running around, scripts executing, and events occuring in the world, you're probably asking how one can understand the flow of execution in an UnrealScript. The answer is as follows:

To manage time, Unreal divides each second of gameplay into "Ticks". A tick is the smallest unit of time in which all actors in a level are updated. A tick typically takes between 1/100th to 1/10th of a second. The tick time is limited only by CPU power; the faster machine, the lower the tick duration is.

Some commands in UnrealScript take zero ticks to execute (i.e. they execute without any game-time passing), and others take many ticks. Functions which require game-time to pass are called "latent functions". Some examples of latent functions include "Sleep", "FinishAnim", and "MoveTo". Latent functions in UnrealScript may only be called from code within a state, not from code within a function.

While an actor is executing a latent function, that actor's state execution doesn't continue until the latent function completes. However, other actors, or the VM, may call functions within the actor. The net result is that all UnrealScript functions can be called at any time, even while latent functions are pending.

In traditional programming terms, UnrealScript acts as if each actor in a level has its own "thread" of execution. Internally, Unreal does not use Windows threads, because that would be very inefficient (Windows 95 and Windows NT do not handle thousands of simultaneous threads efficiently). Instead, UnrealScript simulates threads. This fact is transparent to UnrealScript code, but becomes very apparent when you write C++ code which interacts with UnrealScript.

All UnrealScripts execute in parallel. If there are 100 monsters walking around in a level, all 100 of those monsters' scripts are executing simultaneously and independently.

Class overview

Before beginning work with UnrealScript, it’s important to understand the high-level relationships of objects within Unreal. The architecture of Unreal is a major departure from that of most other games: Unreal is purely object-oriented (much like COM/ActiveX), in that it has a well-defined object model with support for high-level object oriented concepts such as the object graph, serialization, object lifetime, and polymorphism. Historically, most games have been designed monolithically, with their major functionality hardcoded and unexpandable at the object level, though many games, such as Doom and Quake, have proven to be very expandable at the content level. There is a major benefit to Unreal’s form of object-orientation: major new functionality and object types can be added to Unreal at runtime, and this expansion can take the form of subclassing, rather than (for example) by modifying a bunch of existing code. This form of extensibility is extremely powerful, as it encourages the Unreal community to create Unreal enhancements that all interoperate.

Object is the parent class of all objects in Unreal. All of the functions in the Object class are accessible everywhere, because everything derives from Object. Object is an abstract base class, in that it doesn’t do anything useful. All functionality is provided by subclasses, such as Texture (a texture map), TextBuffer (a chunk of text), and Class (which describes the class of other objects).

Actor (expands Object) is the parent class of all standalone game objects in Unreal. The Actor class contains all of the functionality needed for an actor to move around, interact with other actors, affect the environment, and do other useful game-related things.

Pawn (expands Actor) is the parent class of all creatures and players in Unreal which are capable of high-level AI and player controls.

Class (expands Object) is a special kind of object which describes a class of object. This may seem confusing at first: a class is an object, and a class describes certain objects. But, the concept is sound, and there are many cases where you will deal with Class objects. For example, when you spawn a new actor in UnrealScript, you can specify the new actor’s class with a Class object.

With UnrealScript, you can write code for any Object class, but 99% of the time, you will be writing code for a class derived from Actor. Most of the useful UnrealScript functionality is game-related and deals with actors.

The class declaration

Each script corresponds to exactly one class, and the script begins by declaring the class, the class’s parent, and any additional information that is relevent to the class. The simplest form is:

class MyClass expands MyParentClass;

Here I am declaring a new class named "MyClass", which inherets the functionality of "MyParentClass". Additionally, the class resides in the package named "MyPackage".

Each class inherets all of the variables, functions, and states from its parent class. It can then add new variable declarations, add new functions (or override the existing functions), add new states (or add functionality to the existing states).

The typical approach to class design in UnrealScript is to make a new class (for example a Minotaur monster) which expands an existing class that has most of the functionality you need (for example the Pawn class, the base class of all monsters). With this approach, you never need to reinvent the wheel – you can simply add the new functionality you want to customize, while keeping all of the existing functionality you don’t need to customize. This approach is especially powerful for implementing AI in Unreal, where the built-in AI system provides a tremendous amount of base functionality which you can use as building blocks for your custom creatures.

The class declaration can take several optional specifiers that affect the class:

  • native: Says "this class uses behind-the-scenes C++ support". Unreal expects native classes to contain a C++ implementation in the DLL corresponding to the class’s package. For example, if your package is named "Robots", Unreal looks in the "Robots.dll" for the C++ implementation of the native class, which is generated by the C++ IMPLEMENT_CLASS macro.
  • Abstract: Declares the class as an "abstract base class". This prevents the user from adding actors of this class to the world in UnrealEd, because the class isn’t meaningful on its own. For example, the "Pawn
    base class is abstract, while the "Brute" subclass is not abstract – you can place a Brute in the world, but you can’t place a Pawn in the world.
  • guid(a,b,c,d): Associates a globally unique identifier (a 128-bit number) with the class. This Guid is currently unused, but will be relevent when native COM support is later added to Unreal.
  • transient: Says "objects belonging to this class should never be saved on disk". Only useful in conjunction with certain kinds of native classes which are non-persistent by nature, such as players or windows.
  • config(section_name): If there are any configurable variables in the class (declared with "config" or "globalconfig"), causes those variables to be stored in a particular configuration file:
    • config(system): Uses the system configuration file, Unreal.ini for Unreal.
    • config(user): Uses the user configuration file, currently User.ini.
    • config(whatever): Uses the specified configuration file, for example "whatever.ini".

Config(configname)

Variables

Simple Variables

Here are some examples of instance variable declarations in UnrealScript:

var int a; // Declare an integer variable named "A".
var byte Table[64]; // Declare an array of 64 bytes named "Table".
var string[32] PlayerName; // Declare a max 32-character string.
var actor Other; // Declare a variable referencing an actor.

Variables can appear in two kinds of places in UnrealScript: instance variables, which apply to an entire object, appear immediately after the class declarations. Local variables appear within a function, and are only active while that function executes. Instance variables are declared with the "var" keyword. Local variables are declard with the "local" keyword.

Here are the basic variable types supported in UnrealScript:

  • byte: A single-byte value ranging from 0 to 255.
  • int: A 32-bit integer value.
  • bool: A boolean value: either "true" or "false".
  • float: A 32-bit floating point number.
  • string: A string of characters.
  • name: The name of an item in Unreal (such as the name of a function, state, class, etc). Names are stored as a 16-bit index into the global name table. Names correspond to simple strings of 1-31 characters. Names are not like strings: strings can be modified dynamically, but names can only take on predefined name values.
  • Enumeration: A variable that can take on one of several predefined name values. For example, the ELightType enumeration defined in the Actor script describes a dynamic light and takes on a value like LT_None, LT_Pulse, LT_Strobe, and so on.
  • Object and actor references: A variable that refers to another object or actor in the world. For example, the Pawn class has an "Enemy" actor reference that specifies which actor the pawn should be trying to attack. Object and actor references are very powerful tools, because they enable you to access the variables and functions of another actor. For example, in the Pawn script, you can write "Enemy.Damage(123)" to call your enemy’s Damage function – resulting in the enemy taking damage. Object references may also contain a special value called "None", which is the equivalent of the C "NULL" pointer: it says "this variable doesn’t refer to any object".
  • Structs: Similar to C structures, UnrealScript structs let you create new variable types that contain sub-variables. For example, two commonly-used structs are "vector", which consists of an X, Y, and Z component; and "rotator", which consists of a pitch, yaw, and roll component.

Variables may also contain additional specifiers such as "const" that further describe the variable. Actually, there are quite a lot of specifiers which you wouldn’t expect to see in a general-purpose programming language, mainly as a result of wanting UnrealScript to natively support many game- and environment- specific concepts:

  • const: Advanced. Treats the contents of the variable as a constant. In UnrealScript, you can read the value of const variables, but you can’t write to them. "Const" is only used for variables which the engine is responsible for updating, and which can’t be safely updated from UnrealScript, such as an actor’s Location (which can only be set by calling the MoveActor function).
  • input: Advanced. Makes the variable accessible to Unreal’s input system, so that input (such as button presses and joystick movements) can be directly mapped onto it. Only relevent with variables of type "byte" and "float".
  • transient: Advanced. Declares that the variable is for temporary use, and isn’t part of the object’s persistent state. Transient variables are not saved to disk. Transient variables are initialized to zero when an actor is loaded.
  • native: Advanced. Declares that the variable is loaded and saved by C++ code, rather than by UnrealScript.
  • private: The variable is private, and may only be accessed by the class's script; no other classes (including subclasses) may access it.

Arrays are declared using the following syntax:

var int MyArray[20]; // Declares an array of 20 ints.

UnrealScript supports only single-dimensional arrays, though you can simulate multidimensional arrays by carrying out the row/column math yourself.

In UnrealScript, you can make an instance variable "editable", so that users can edit the variable’s value in UnrealEd. This mechanism is responsible for the entire contents of the "Actor Properties" dialog in UnrealEd: everything you see there is simply an UnrealScript variable, which has been declared editable.

The syntax for declaring an editable variable is as follows:

var() int MyInteger; // Declare an editable integer in the default category.
var(MyCategory) bool MyBool; // Declare an editable integer in "MyCategory".

Object and actor reference variables

You can declare a variable that refers to an actor or object like this:

var actor A; // An actor reference.
var pawn P; // A reference to an actor in the Pawn class.
var texture T; // A reference to a texture object.

The variable "P" above is a reference to an actor in the Pawn class. Such a variable can refer to any actor that belongs to a subclass of Pawn. For example, P might refer to a Brute, or a Skaarj, or a Manta. It can be any kind of Pawn. However, P can never refer to a Trigger actor (because Trigger is not a subclass of Pawn).

One example of where it’s handy to have a variable refering to an actor is the Enemy variable in the Pawn class, which refers to the actor which the Pawn is trying to attack.

When you have a variable that refers to an actor, you can access that actor’s variables, and call its functions. For example:

// Declare two variables that refer to a pawns.
var pawn P, Q;

// Here is a function that makes use of P.
// It displays some information about P.
function MyFunction()
{
    // Set P’s enemy to Q.
    P.Enemy = Q;

    // Tell P to play his running animation.
    P.PlayRunning();
}

Variables that refer to actors always either refer to a valid actor (any actor that actually exists in the level), or they contain the value "None". None is equivalent to the C/C++ "NULL" pointer. However, in UnrealScript, it is safe to access variables and call functions with a "None" reference; the result is always zero.

Note that an object or actor reference "points to" another actor or object, it doesn’t "contain" an actor or object. The C equivalent of an actor reference is a pointer to an object in the AActor class (in C, you’d say an AActor*). For example, you could have two monsters in the world, Bob and Fred, who are fighting each other. Bob’s "Enemy" variable would "point to" Fred, and Fred’s "Enemy" variable would "point to" Bob.

Unlike C pointers, UnrealScript object references are always safe and infallible. It is impossible for an object reference to refer to an object that doesn’t exist or is invalid (other than the special-case "None" value). In UnrealScript, when an actor or object is destroyed, all references to it are automatically set to "None".

Class Reference Variables

In Unreal, classes are objects just like actors, textures, and sounds are objects. Class objects belong to the class named "class". Now, there will often be cases where you'll want to store a reference to a class object, so that you can spawn an actor belonging to that class (without knowing what the class is at compile-time). For example:

var() class C;
var actor A;
A = Spawn( C ); // Spawn an actor belonging to some arbitrary class C.

Now, be sure not to confuse the roles of a class C, and an object O belonging to class C. To give a really shaky analogy, a class is like a pepper grinder, and an object is like pepper. You can use the pepper grinder (the class) to create pepper (objects of that class) by turning the crank (calling the Spawn function)...BUT, a pepper grinder (a class) is not pepper (an object belonging to the class), so you MUST NOT TRY TO EAT IT!

When declaring variables that reference class objects, you can optionally use the special class<classlimitor> syntax to limit the variable to only containing references to classes which expand a given superclass. For example, in the declaration:

var class<actor> ActorClass;

The variable ActorClass may only reference a class that expands the "actor" class. This is useful for improving compile-time type checking. For example, the Spawn function takes a class as a parameter, but only makes sense when the given class is a subclass of Actor, and the class<classlimitor> syntax causes the compiler to enforce that requirement.

As with dynamic object casting, you can dynamically cast classes like this:

class<actor>( SomeFunctionCall() )

Enumerations

Enumerations exist in UnrealScript as a convenient way to declare variables that can contain "one of" a bunch of keywords. For example, the actor class contains the enumeration EPhysics which describes the physics which Unreal should apply to the actor. This can be set to one of the predefined values like PHYS_None, PHYS_Walking, PHYS_Falling, and so on.

Internally, enumerations are stored as byte variables. In designing UnrealScript, enumerations were not seen as a necessity, but it makes code so much easier to read to see that an actor’s physics mode is being set to "PHYS_Swimming" than (for example) "3".

Here is sample code that declares enumerations.

// Declare the EColor enumeration, with three values.
enum EColor
{
    CO_Red,
    CO_Green,
    CO_Blue
};

// Now, declare two variables of type EColor.
var EColor ShirtColor, HatColor;

// Alternatively, you can declare variables and
// enumerations together like this:
var enum EFruit
{
    FRUIT_Apple,
    FRUIT_Orange,
    FRUIT_Bannana
} FirstFruit, SecondFruit;

In the Unreal source, we always declare enumeration values like LT_Steady, PHYS_Falling, and so on, rather than as simply "Steady" or "Falling". This is just a matter of programming style, and is not a requirement of the language.

UnrealScript only recognizes unqualified enum tags (like FRUIT_Apple) in classes where the enumeration was defined, and in its subclasses. If you need to refer to an enumeration tag defined somewhere else in the class hierarchy, you must "qualify it":

FRUIT_Apple // If Unreal can't find this enum tag...
EFruit.FRUIT_Apple // Then qualify it like this.

Structs

An UnrealScript struct is a way of cramming a bunch of variables together into a new kind of super-variable called a struct. UnrealScript structs are just like C structs, in that they can contain any simple variables or arrays.

You can declare a struct as follows:

// A point or direction vector in 3D space.
struct Vector
{
    var float X;
    var float Y;
    var float Z
};

Once you declare a struct, you are ready to start declaring specific variables of that struct type:

// Declare a bunch of variables of type Vector.
var Vector Position;
var Vector Destination;

To access a component of a struct, use code like the following.

function MyFunction()
{
    Local Vector A, B, C;

    // Add some vectors.
    C = A + B;

    // Add just the x components of the vectors.
    C.X = A.X + B.X;

    // Pass vector C to a function.
    SomeFunction( C );

    // Pass certain vector components to a function.
    OtherFunction( A.X, C.Z );
}

You can do anything with Struct variables that you can do with other variables: you can assign variables to them, you can pass them to functions, and you can access their components.

There are several Structs defined in the Object class which are used throughout Unreal. You should become familiar with their operation, as they are fundamental building blocks of scripts:

  • Vector: A unique 3D point or vector in space, with an X, Y, and Z component.
  • Plane: Defines a unique plane in 3D space. A plane is defined by its X, Y, and Z components (which are assumed to be normalized) plus its W component, which represents the distance of the plane from the origin, along the plane’s normal (which is the shortest line from the plane to the origin).
  • Rotation: A rotation defining a unique orthogonal coordinate system. A rotation contains Pitch, Yaw, and Roll components.
  • Coords: An arbitrary coordinate system in 3D space.
  • Color: An RGB color value.
  • Region: Defines a unique convex region within a level.

Expressions

Constants

In UnrealScript, you can specify constant values of nearly all data types:

  • Integer and byte constants are specified with simple numbers, for example: 123
  • If you must specify an integer or byte constant in hexidecimal format, use i.e.: 0x123
  • Floating point constants are specified with decimal numbers like: 456.789
  • String constants must be enclosed in double quotes, for example: "MyString"
  • Name constants must be enclosed in single quotes, for example ‘MyName’
  • Vector constants contain X, Y, and Z values like this: Vect(1.0,2.0,4.0)
  • Rotation constants contant Pitch, Yaw, and Roll values like this: Rot(0x8000,0x4000,0)
  • The "None" constant refers to "no object" (or equivalantly, "no actor").
  • The "Self" constant refers to "this object" (or equivalantly, "this actor"), i.e. the object whose script is executing.
  • General object constants are specified by the object type followed by the object name in single quotes, for example: texture ‘Default’
  • EnumCount gives you the number of elements in an enumeration, for example: EnumCount(ELightType)
  • ArrayCount gives you the number of elements in an array, for example: ArrayCount(Touching)

You can use the "const" keyword to declare constants which you can later refer to by name. For example:

const LargeNumber=123456;
const PI=3.14159;
const MyName="Tim";
const Northeast=Vect(1.0,1.0,0.0);

Constants can be defined within classes or within structs.

To access a constant which was declared in another class, use the "classname.constname" syntax, for example:

Pawn.LargeNumber

Expressions

To assign a value to a variable, use "=" like this:

function Test()
{
    local int i;
    local string[80] s;
    local vector v, q;

    i = 10; // Assign a value to integer variable i.
    s = "Hello!"; // Assign a value to string variable s.
    v = q; // Copy value of vector q to v.
}

In UnrealScript, whenever a function or other expression requires a certain type of data (for example, an "float"), and you specify a different type of data (for example, an "int), the compiler will try to convert the value you give to the proper type. Conversions among all the numerical data types (byte, int, and float) happen automatically, without any work on your part.

UnrealScript is also able to many other built-in data types to other types, if you explicitly convert them in code. The syntax for this is:

function Test()
{
    local int i;
    local string[80] s;
    local vector v, q;
    local rotation r;

    s = string(i); // Convert integer i to a string, and assign it to s.
    s = string(v); // Convert vector v to a string, and assign it to s.
    v = q + vector(r); // Convert rotation r to a vector, and add q.
}

Here is the complete set of non-automatic conversions you can use in UnrealScript:

  • String to Byte, Int, Float: Tries to convert a string like "123" to a value like 123. If the string doesn’t represent a value, the result is 0.
  • Byte, Int, Float, Vector, Rotation to String: Converts the number to its textual representation.
  • String to Vector, Rotation: Tries to parse the vector or rotation’s textual representation.
  • String to Bool: Converts the case-insensitive words "True" or "False" to True and False; converts any non-zero value to True; everything else is False.
  • Bool to String: Result is either "True" or "False".
  • Byte, Int, Float, Vector, Rotation to Bool: Converts nonzero values to True; zero values to False.
  • Bool to Byte, Int, Float: Converts True to 1; False to 0.
  • Name to String: Converts the name to the text equivalant.
  • Rotation to Vector: Returns a vector facing "forward" according to the rotation.
  • Vector to Rotation: Returns a rotation pitching and yawing in the direction of the vector; roll is zero.
  • Object (or Actor) to Int: Returns an integer that is guaranteed unique for that object.
  • Object (or Actor) to Bool: Returns False if the object is None; False otherwise.
  • Object (or Actor) to String: Returns a textual representation of the object.

Converting object references among classes

Just like the conversion functions above, which convert among simple datatypes, in UnrealScript you can convert actor and object references among various types. For example, all actors have a variable named "Target", which is a reference to another actor. Say you are writing a script where you need to check and see if your Target belongs to the "Pawn" actor class, and you need to do something special with your target that only makes sense when it’s a pawn -- for example, you need to call one of the Pawn functions. The actor cast operators let you do this. Here’s an example:

var actor Target;
//...

function TestActorConversions()
{
    local Pawn P;

    // See if my target is a Pawn.
    P = Pawn(Target);
    if( P != None )
    {
        // Target is a pawn, so set its Enemy to Self.
        P.Enemy = Self;
    }
    else
    {
        // Target is not a pawn.
    }
}

To perform an actor conversion, type the class name followed by the actor expression you wish to convert, in parenthesis. Such a conversion will either succeed or fail based on whether the conversion is sensible. In the above example, if your Target is referencing a Trigger object rather than a pawn, the expression Pawn(Target) will return "None", since a Trigger can’t be converted to a Pawn. However, if your Target is referencing a Brute object, the conversion will successfully return the Brute, because Brute is a subclass of Pawn.

Thus, actor conversions have two purposes: First, you can use them to see if a certain actor reference belongs to a certain class. Second, you can use them to convert an actor reference from one class to a more specific class. Note that these conversions don’t affect the actor you’re converting at all -- they just enable UnrealScript to treat the actor reference as if it were a more specific type.

Another example of conversions lies in the Inventory script. Each Inventory actor is owned by a Pawn, even though its Owner variable can refer to any Actor. So a common theme in the Inventory code is to cast Owner to a Pawn, for example:

// Called by engine when destroyed.
function Destroyed()
{
    // Remove from owner's inventory.
    if( Pawn(Owner)!=None )
        Pawn(Owner).DeleteInventory( Self );
}

Functions

Declaring Functions

In UnrealScript, you can declare new functions and write new versions of existing functions. Functions can take one or more parameters (of any variable type UnrealScript supports), and can optionally return a value. Though most functions are written directly in UnrealScript, you can also declare functions that can be called from UnrealScript, but which are implemented in C++ and reside in a DLL. The Unreal technology supports all possible combinations of function calling: The C++ engine can call script functions; script can call C++ functions; and script can call script.

Here is a simple function declaration. This function takes a vector as a parameter, and returns a floating point number:

// Function to compute the size of a vector.
function float VectorSize( vector V )
{
    return sqrt( V.X * V.X + V.Y * V.Y + V.Z * V.Z );
}

The word "function" always precedes a function declaration. It is followed by the optional return type of the function (in this case, "float"), then the function name, and then the list of function parameters enclosed in parenthesis.

When a function is called, the code within the brackets is executed. Inside the function, you can declare local variables (using the "local" keyword"), and execute any UnrealScript code. The optional "return" keyword causes the function to immediately return a value.

You can pass any UnrealScript types to a function (including arrays), and a function can return any type.

By default, any local variables you declare in a function are initialized to zero.

Function calls can be recursive. For example, the following function computes the factorial of a number:

// Function to compute the factorial of a number.
function int Factorial( int Number )
{
    if( Number <= 0 )
        return 1;
    else
        return Number * Factorial( Number – 1 );
}

Some UnrealScript functions are called by the engine whenever certain events occur. For example, when an actor is touched by another actor, the engine calls its "Touch" function to tell it who is touching it. By writing a custom "Touch" function, you can take special actions as a result of the touch occuring:

// Called when something touches this actor.
function Touch( actor Other )
{
    Log( "I was touched!")
    Other.Message( "You touched me!" );
}

The above function illustrates several things. First of all, the function writes a message to the log file using the "Log" command (which is the equivalent of Basic’s "print" command and C’s "printf"). Second, it calls the "Message" function residing in the actor Other. Calling functions in other actors is a common action in UnrealScript, and in object-oriented languages like Java in general, because it provides a simple means for actors to communicate with each other.

Function parameter specifiers

When you normally call a function, UnrealScript makes a local copy of the parameters you pass the function. If the function modifies some of the parameters, those don’t have any effect on the variables you passed in. For example, the following program:

function int DoSomething( int x )
{
    x = x * 2;
    return x;
}
function int DoSomethingElse()
{
    local int a, b;

    a = 2;
    log( "The value of a is " $ a );

    b = DoSomething( a );
    log( "The value of a is " $ a );
    log( "The value of b is " $ b );
}

Produces the following output when DoSomethingElse is called:

The value of a is 2
The value of a is 2
The value of b is 4

In other words, the function DoSomething was futzing with a local copy of the variable "a" which was passed to it, and it was not affecting the real variable "a".

The "out" specified lets you tell a function that it should actually modify the variable that is passed to it, rather than making a local copy. This is useful, for example, if you have a function that needs to return several values to the caller. You can juse have the caller pass several variables to the function which are "out" values. For example:

// Compute the minimum and maximum components of a vector.
function VectorRange( vector V, out float Min, out float Max )
{
    // Compute the minimum value.
    if ( V.X<V.Y && V.X<V.Z ) Min = V.X;
    else if( V.Y<V.Z ) Min = V.Y;
    else Min = V.Z;

    // Compute the maximum value.
    if ( V.X>V.Y && V.X>V.Z ) Max = V.X;
    else if( V.Y>V.Z ) Max = V.Y;
    else Max = V.Z;
}

Without the "out" keyword, it would be painful to try to write functions that had to return more than one value.

With the "optional" keyword, you can make certain function parameters optional, as a convenience to the caller. For UnrealScript functions, optional parameters which the caller doesn’t specify are set to zero. For native functions, the default values of optional parameters depends on the function. For example, the Spawn function takes an optional location and rotation, which default to the spawning actor’s location and rotation.

The "coerce" keyword forces the caller’s parameters to be converted to the specified type (even if UnrealScript normally would not perform the conversion automatically). This is useful for functions that deal with strings, so that the parameters are automatically converted to strings for you.

Function overriding

"Function overriding" refers to writing a new version of a function in a subclass. For example, say you’re writing a script for a new kind of monster called a Demon. The Demon class, which you just created, expands the Pawn class. Now, when a pawn sees a player for the first time, the pawn’s "SeePlayer" function is called, so that the pawn can start attacking the player. This is a nice concept, but say you wanted to handle "SeePlayer" differently in your new Demon class. How do you do this? Function overriding is the answer.

To override a function, just cut and paste the function definition from the parent class into your new class. For example, for SeePlayer, you could add this to your Demon class.

// New Demon class version of the Touch function.
function SeePlayer( actor SeenPlayer )
{
    log( "The demon saw a player" );
    // Add new custom functionality here…
}

Function overriding is the key to creating new UnrealScript classes efficiently. You can create a new class that expands on an existing class. Then, all you need to do is override the functions which you want to be handled differently. This enables you to create new kinds of objects without writing gigantic amounts of code.

Several functions in UnrealScript are declared as "final". The "final" keyword (which appears immediately before the word "function") says "this function cannot be overridden by child classes". This should be used in functions which you know nobody would want to override, because it results in faster script code. For example, say you have a "VectorSize" function that computes the size of a vector. There’s absolutely no reason anyone would ever override that, so declare it as "final". On the other hand, a function like "Touch" is very context-dependent and should not be final.

Advanced function specifiers

Static: A static function acts like a C global function, in that it can be called without having a reference to an object of the class. Static functions can call other static functions, and can access the default values of variables. Static functions cannot call non-static functions and they cannot access instance variables (since they are not executed with respect to an instance of an object). Unlike languages like C++, static functions are virtual and can be overridden in child classes. This is useful in cases where you wish to call a static function in a variable class (a class not known at compile time, but referred to by a variable or an expression).

Singular: The "singular" keyword, which appears immediately before a function declaration, prevents a function from calling itself recursively. The rule is this: If a certain actor is already in the middle of a singular function, any subsequent calls to singular functions will be skipped over. This is useful in avoiding infinite-recursive bugs in some cases. For example, if you try to move an actor inside of your "Bump" function, there is a good chance that the actor will bump into another actor during its move, resulting in another call to the "Bump" function, and so on. You should be very careful in avoiding such behaviour, but if you can’t write code with complete confidence that you’re avoiding such potential recursive situations, use the "singular" keyword.

Native: You can declare UnrealScript functions as "native", which means that the function is callable from UnrealScript, but is actually written (elsewhere) in C++. For example, the Actor class contains a lot of native function definitions, such as:

native(266) final function bool Move( vector Delta );

The number inside the parenthesis after the "native" keyword corresponds to the number of the function as it was declared in C++ (using the AUTOREGISTER_NATIVE macro). The native function is expected to reside in the DLL named identically to the package of the class containing the UnrealScript definition.

Latent: Declares that an native function is latent, meaning that it can only be called from state code, and it may return after some game-time has passed.

Iterator: Declares that an native function is an iterator, which can be used to loop through a list of actors using the "foreach" command.

Simulated: Declares that a function may execute on the client-side when an actor is either a simulated proxy or an autonomous proxy. All functions that are both native and final are automatically simulated as well.

Operator, PreOperator, PostOperator: These keywords are for declaring a special kind of function called an operator (equivalent to C++ operators). This is how UnrealScript knows about all of the built-in operators like "+", "-", "==", and "||". I'm not going into detail on how operators work in this document, but the concept of operators is similar to C++, and you can declare new operator functions and keywords as UnrealScript functions or native functions.

Event: The "event" keyword has the same meaning to UnrealScript as "function". However, when you export a C++ header file from Unreal using "unreal -make -h", UnrealEd automatically generates a C++ -> UnrealScript calling stub for each "event". This is a much cleaner replacement for the old "PMessageParms" struct, because it automatically keeps C++ code synched up with UnrealScript functions and eliminates the possibility of passing invalid parameters to an UnrealScript function. For example, this bit of UnrealScript code:

event Touch( Actor Other )
{ ... }

Generates this piece of code in EngineClasses.h:

void Touch(class AActor* Other)
{
    FName N("Touch",FNAME_Intrinsic);
    struct {class AActor* Other; } Parms;
    Parms.Other=Other;
    ProcessEvent(N,&Parms);
}

Thus enabling you to call the UnrealScript function from C++ like this:

AActor *SomeActor, *OtherActor;
Actor->Touch(OtherActor);

Program Structure

UnrealScript supports all the standard flow-control statements of C/C++/Java:

For Loops

"For" loops let you cycle through a loop as long as some condition is met. For example:

// Example of "for" loop.
function ForExample()
{
    local int i;
    log( "Demonstrating the for loop" );
    for( i=0; i<4; i++ )
    {
        log( "The value of i is " $ i );
    }
    log( "Completed with i=" $ i);
}

The output of this loop is:

Demonstrating the for loop
The value of i is 0
The value of i is 1
The value of i is 2
The value of i is 3
Completed with i=4

In a for loop, you must specify three expressions separated by semicolons. The first expression is for initializing a variable to its starting value. The second expression gives a condition which is checked before each iteration of the loop executes; if this expression is true, the loop executes. If it’s false, the loop terminates. The third condition gives an expression which increments the loop counter.

Though most "for" loop expressions just update a counter, you can also use "for" loops for more advanced things like traversing linked lists, by using the appropriate initialization, termination, and increment expressions.

In all of the flow control statements, you can either execute a single statement, without brackets, as follows:

for( i=0; i<4; i++ )
    log( "The value of i is " $ i );

Or you can execute multiple statements, surrounded by brackets, like this:

for( i=0; i<4; i++ )
{
    log( "The value of i is" );
    log( i );
}

Do-While Loops

"Do"-"Until" loops let you cycle through a loop while some ending expression is true. Note that Unreal's do-until syntax differs from C/Java (which use do-while).

// Example of "do" loop.
function DoExample()
{
    local int i;
    log( "Demonstrating the do loop" );
    do
    {
        log( "The value of i is " $ i );
        i = i + 1;
    } until( i == 4 );
    log( "Completed with i=" $ i);
}

The output of this loop is:

Demonstrating the do loop
The value of i is 0
The value of i is 1
The value of i is 2
The value of i is 3
Completed with i=4

While Loops

"While" loops let you cycle through a loop while some starting expression is true.

// Example of "while" loop.
function WhileExample()
{
    local int i;
    log( "Demonstrating the while loop" );
    while( i < 4 )
    {
        log( "The value of i is " $ i );
        i = i + 1;
    }
    log( "Completed with i=" $ i);
}

The output of this loop is:

Demonstrating the do loop
The value of i is 0
The value of i is 1
The value of i is 2
The value of i is 3
Completed with i=4

Break

The "break" command exits out of the nearest loop ("For", "Do", or "While").

// Example of "while" loop.
function WhileExample()
{
    local int i;
    log( "Demonstrating break" );
    for( i=0; i<10; i++ )
    {
        if( i == 3 )
            break;
        log( "The value of i is " $ i );
    }
    log( "Completed with i=" $ i );
}

The output of this loop is:

Demonstrating break
The value of i is 0
The value of i is 1
The value of i is 2
Completed with i=3

Goto

The "Goto" command goes to a label somewhere in the current function or state.

// Example of "goto".
function GotoExample()
{
    log( "Starting GotoExample" );
    goto Hither;
Yon:
    log( "At Yon" );
    goto Elsewhere;
Hither:
    log( "At Hither" );
    goto Yon;
Elsewhere:
    log( "At Elsewhere" );
}

The output is:

Starting GotoExample
At Hither
At Yon
At Elsewhere

Conditional Statements

"If", "Else If", and "Else" let you execute code if certain conditions are met.

// Example of simple "if".
if( LightBrightness < 20 )
    log( "My light is dim" );

// Example of "if-else".
if( LightBrightness < 20 )
    log( "My light is dim" );
else
    log( "My light is bright" );

// Example if "if-else if-else".
if( LightBrightness < 20 )
    log( ‘My light is dim" );
else if( LightBrightness < 40 )
    log( "My light is medium" );
else if( LightBrightness < 60 )
    log( "My light is kinda bright" );
else
    log( "My light is very bright" );

// Example if "if" with brackets.
if( LightType == LT_Steady )
{
    log( "Light is steady" );
}
else
{
    log( "Light is not steady" );
}

Case Statements

"Switch", "Case", "Default", and "Break" let you handle lists of conditions easily.

// Example of switch-case.
function TestSwitch()
{
    // Executed one of the case statements below, based on
    // the value in LightType.
    switch( LightType )
    {
        case LT_None:
            log( "There is no lighting" );
            break;
        case LT_Steady:
            log( "There is steady lighting" );
            break;
        case LT_Backdrop:
            log( "There is backdrop lighting" );
            break;
        default:
            log( "There is dynamic" );
            break;
    }
}

A "switch" statement consists of one or more "case" statements, and an optional "default" statement. After a switch statement, execution goes to the matching "case" statement if there is one; otherwise execution goes to the "default" statement; otherwise execution continues past the end of the "select" statement.

After you write code following a "case" label, you must use a "break" statement to cause execution to go past the end of the "switch" statement. If you don’t use a "break", execution "falls through" to the next "case" handler.

States

Overview of States

Historically, game programmers have been using the concept of states ever since games evolved past the "pong" phase. States (and what is known as "state machine programming") are a natural way of making complex object behaviour manageable. However, before UnrealScript, states have not been supported at the language level, requiring developers to create C/C++ "switch" statements based on the object’s state. Such code was difficult to write and update.

UnrealScript supports states at the language level.

In UnrealScript, each actor in the world is always in one and only one state. Its state reflects the action it wants to perform. For example, moving brushes have several states like "StandOpenTimed" and "BumpOpenTimed". Pawns have several states such as "Dying", "Attacking", and "Wandering".

In UnrealScript, you can write functions and code which exist in a particular state. These functions are only called when the actor is in that state. For example, say you’re writing a monster script, and you’re contemplating how to handle the "SeePlayer" function. When you’re wandering around, you want to attack the player you see. When you’re already attacking the player, you want to continue on uninterrupted.

The easiest way to do this is by defining several states (Wandering and Attacking), and writing a different version of "Touch" in each state. UnrealScript supports this.

Before delving deeper into states, you need to understand that there are two major benefits to states, and one complication:

  • Benefit: States provide a simple way to write state-specific functions, so that you can handle the same function in different ways, depending on what the actor is doing.
  • Benefit: With a state, you can write special "state code", using all of the regular UnrealScript commands plus several special functions known as "latent functions". A latent function is a function which executes "slowly", and may return after a certain amount of "game time" has passed. This enables you to perform time-based programming – a major benefit which neither C, C++, nor Java offer. Namely, you can write code in the same way you conceptualize it; for example, you can write a script that says the equivalent of "open this door; pause 2 seconds; play this sound effect; open that door; release that monster and have it attack the player". You can do this with simple, linear code, and the Unreal engine takes care of the details of managing the time-based execution of the code.
  • Complication: Now that you can have functions (like "Touch") overridden in multiple states as well as in child classes, you have the burden of figuring out exactly which "Touch" function is going to be called in a specific situation. UnrealScript provides rules which clearly delineate this process, but it is something you must be aware of if you create complex hierarchies of classes and states.

Here is an example of states from the TriggerLight script:

// Trigger turns the light on.
state() TriggerTurnsOn
{
    function Trigger( actor Other, pawn EventInstigator )
    {
        Trigger = None;
        Direction = 1.0;
        Enable( 'Tick' );
    }
}

// Trigger turns the light off.
state() TriggerTurnsOff
{
    function Trigger( actor Other, pawn EventInstigator )
    {
        Trigger = None;
        Direction = -1.0;
        Enable( 'Tick' );
    }
}

Here you are declaring two different states (TriggerTurnsOn and TriggerTurnsOff), and you’re writing a different version of the Trigger function in each state. Though you could pull off this implementation without states, using states makes the code far more modular and expandable: in UnrealScript, you can easily subclass an existing class, add new states, and add new functions. If you had tried to do this without states, the resulting code would be more difficult to expand later.

A state can be declared as editable, meaning that the user can set an actor’s state in UnrealEd, or not. To declare an editable state, do the following:

state() MyState
{
    //...
}

To declare a non-editable state, do this:

state MyState
{
    //...
}

You can also specify the automatic, or initial state that an actor should be in by using the "auto" keyword. This causes all new actors to be placed in that state when they first are activated:

auto state MyState
{
    //...
}

State Labels and Latent Functions

In addition to functions, a state can contain one or more labels followed by UnrealScript code. For example:

auto state MyState
{
Begin:
    Log( "MyState has just begun!" );
    Sleep( 2.0 );
    Log( "MyState has finished sleeping" );
    goto Begin;
}

The above state code prints the message "MyState has just begun!", then it pauses for two seconds, then it prints the message "MyState has finished sleeping". The interesting thing in this example is the call to the latent function "Sleep": this function call doesn’t return immediately, but returns after a certain amount of game time has passed. Latent functions can only be called from within state code, and not from within functions. Latent functions let you manage complex chains of events which include the passage of time.

All state code begins with a label definition; in the above example the label is named "Begin". The label provides a convenient entry point into the state code. You can use any label name in state code, but the "Begin" label is special: it is the default starting point for code in that state.

There are three main latent functions available to all actors:

  • Sleep( float Seconds ) pauses the state execution for a certain amount of time, and then continues.
  • FinishAnim() waits until the current animation sequence you’re playing completes, and then continues. This function makes it easy to write animation-driven scripts, scripts whose execution is governed by mesh animations. For example, most of the AI scripts are animation-driven (as opposed to time-driven), because smooth animation is a key goal of the AI system.
  • FinishInterpolation() waits for the current InterpolationPoint movement to complete, and then continues.

The Pawn class defines several important latent functions for actions such as navigating through the world and short-term movement. See the separate AI docs for descriptions of their usage.

Three native UnrealScript functions are particularly useful when writing state code:

  • The "Goto" function (similar to the C/C++/Basic goto) within a state causes the state code to continue executing at a different label.
  • The special Goto('') command within a state causes the state code execution to stop. State code execution doesn’t continue until you go to a new state, or go to a new label within the current state.
  • The "GotoState" function causes the actor to go to a new state, and optionally continue at a specified label (if you don’t specify a label, the default is the "Begin" label). You can call GotoState from within state code, and it goes to the destination immediately. You can also call GotoState from within any function in the actor, but that does not take effect immediately: it doesn’t take effect until execution returns back to the state code.

Here is an example of the state concepts discussed so far:

// This is the automatic state to execute.
auto state Idle
{
    // When touched by another actor…
    function Touch( actor Other )
    {
        log( "I was touched, so I’m going to Attacking" );
        GotoState( ‘Attacking’ );
        Log( "I have gone to the Attacking state" );
    }
Begin:
    log( "I am idle…" );
    sleep( 10 );
    goto ‘Begin’;
}

// Attacking state.
state Attacking
{
Begin:
    Log( "I am executing the attacking state code" );
    //...
}

When you run this program and then go touch the actor, you will see:

I am idle...
I am idle...
I am idle...
I was touched, so I’m going to Attacking
I have gone to the Attacking state
I am executing the attacking state code

Make sure you understand this important aspect of GotoState: When you call GotoState from within a function, it does not go to the destination immediately, rather it goes there once execution returns back to the state code.

State inheretance and scoping rules

In UnrealScript, when you subclass an existing class, your new class inherets all of the variables, functions and states from its parent class. This is well-understood.

However, the addition of the state abstraction to the UnrealScript programming model adds additional twists to the inheretance and scoping rules. The complete inheretance rules are:

  • A new class inherets all of the variables from its parent class.
  • A new class inherents all of its parent class’s non-state functions. You can override any of those inhereted non-state functions. You can add entirely new non-state functions.
  • A new class inherets all of its parent class’s states, including the functions and labels within those states. You can override any of the inhereted state functions, and you can override any of the inhereted state labels, you can add new state functions, and you can add new state labels.

Here is an example of all the overriding rules:

// Here is an example parent class.
class MyParentClass expands Actor;

// A non-state function.
function MyInstanceFunction()
{
    log( "Executing MyInstanceFunction" );
}

// A state.
state MyState
{
    // A state function.
    function MyStateFunction()
    {
        Log( "Executing MyStateFunction" );
    }
// The "Begin" label.
Begin:
    Log("Beginning MyState");
}

// Here is an example child class.
class MyChildClass expands MyParentClass;

// Here I’m overriding a non-state function.
function MyInstanceFunction()
{
    Log( "Executing MyInstanceFunction in child class" );
}

// Here I’m redeclaring MyState so that I can override MyStateFunction.
state MyState
{
    // Here I’m overriding MyStateFunction.
    function MyStateFunction()
    {
        Log( "Executing MyStateFunction" );
    }
// Here I’m overriding the "Begin" label.
Begin:
    Log( "Beginning MyState in MyChildClass" );
}

When you have a function that is implemented globally, in one or more states, and in one or more parent classes, you need to understand which version of the function will be called in a given context. The scoping rules, which resolves these complex situations, are:

  • If the object is in a state, and an implementation of the function exists somewhere in that state (either in the actor’s class or in some parent class), the most-derived state version of the function is called.
  • Otherwise, the most-derived non-state version of the function is called.

Advanced state programming

If a state doesn’t override a state of the same name in the parent class, then you can optionally use the "expands" keyword to make the state expand on an existing state in the current class. This is useful, for example, in a situatio where you have a group of similar states (such as MeleeAttacking and RangeAttacking) which have a lot of functionality in common. In this case you could declare a base Attacking state as follows:

// Base Attacking state.
state Attacking
{
    // Stick base functions here...
}

// Attacking up-close.
state MeleeAttacking expands Attacking
{
    // Stick specialized functions here...
}

// Attacking from a distance.
state RangeAttacking expands Attacking
{
    // Stick specialized functions here...
}

A state can optionally use the "ignores" specifier to ignore functions while in a state. The syntax for this is:

// Declare a state.
state Retreating
{
    // Ignore the following messages...
    ignores Touch, UnTouch, MyFunction;

    // Stick functions here...
}

You can tell what specific state an actor is in from its "state" variable, a variable of type "name".

It is possible for an actor to be in "no state" by using GotoState(‘’). When an actor is in "no state", only its global (non-state) functions are called.

Whever you use the GotoState command to set an actor’s state, the engine can call two special notification functions, if you have defined them: EndState() and BeginState(). EndState is called in the current state immediately before the new state is begun, and BeginState is called immediately after the new state begins. These functions provide a convenient place to do any state-specific initialization and cleanup which your state may require.

Language Functionality

Built-in operators and their precedence

UnrealScript provides a wide variety of C/C++/Java-style operators for such operations as adding numbers together, comaring values, and incrementing variables. The complete set of operators is defined in Object.u, but here is a recap. Here are the standard operators, in order of precedence. Note that all of the C style operators have the same precedence as they do in C.

Operator | Types it applies to | Meaning
$ | string | String concatenation
*= | byte, int, float, vector, rotation | Multiply and assign
/= | byte, int, float, vector, rotation | Divide and assign
+= | byte, int, float, vector | Add and assign
-= | byte, int, float, vector | Subtract and assign
|| | bool | Logical or
&& | bool | Logical and
& | int | Bitwise and
| | int | Bitwise or
^ | int | Bitwise exlusive or
!= | All | Compare for inequality
== | All | Compare for equality
< | byte, int, float, string | Less than
> | byte, int, float, string | Greater than
<= | byte, int, float, string | Less than or equal to
>= | byte, int, float, string | Greater than or equal to
~= | float, string | Approximate equality (within 0.0001), case-insensitive equality.
<< | int, vector | Left shift (int), Forward vector transformation (vector)
>> | int, vector | Right shift (int), Reverse vector transformation (vector)
+ | byte, int, float, vector | Add
- | byte, int, float, vector | Subtract
% | float | Modulo (remainder after division)
* | byte, int, float, vector, rotation | Multiply
/ | byte, int, float, vector, rotation | Divide
Dot | vector | Vector dot product
Cross | vector | Vector cross product
** | float | Exponentiation

The above table lists the operators in order of precedence (with operators of the same precedence grouped together). When you type in a complex expression like "1*2+3*4", UnrealScript automatically groups the operators by precedence. Since multiplication has a higher precedence than addition, the expression is evaluated as "(1*2)+(3*4)".

The "&&" (logical and) and "||" (logical or) operators are short-circuited: if the result of the expression can be determined solely from the first expression (for example, if the first argument of && is false), the second expression is not evaluated.

In addition, UnrealScript supports the following unary operators:

  • ! (bool) Logical not.
  • - (int, float) negation.
  • ~ (int) bitwise negation.
  • ++, -- Decrement (either before or after a variable).

General purpose functions

Integer functions:

  • int Rand( int Max ); Returns a random number from 0 to Max-1.
  • int Min( int A, int B ); Returns the minimum of the two numbers.
  • int Max( int A, int B ); Returns the maximum of the two numbers.
  • int Clamp( int V, int A, int B ); Returns the first number clamped to the interval from A to B.

Floating point functions:

  • float Abs( float A ); Returns the absolute value of the number.
  • float Sin( float A ); Returns the sine of the number expressed in radius.
  • float Cos( float A ); Returns the cosine of the number expressed in radians.
  • float Tan( float A ); Returns the tangent of the number expressed in radians.
  • float Atan( float A ); Returns the inverse tangent of the number expressed in radians.
  • float Exp( float A ); Returns the constant "e" raised to the power of A.
  • float Loge( float A ); Returns the log (to the base "e") of A.
  • float Sqrt( float A ); Returns the square root of A.
  • float Square( float A ); Returns the square of A = A*A.
  • float FRand(); Returns a random number from 0.0 to 1.0.
  • float FMin( float A, float B ); Returns the minimum of two numbers.
  • float FMax( float A, float B ); Returns the maximum of two numbers.
  • float FClamp( float V, float A, float B ); Returns the first number clamped to the interval from A to B.
  • float Lerp( float Alpha, float A, float B ); Returns the linear interpolation between A and B.
  • float Smerp( float Alpha, float A, float B ); Returns an Alpha-smooth nonlinear interpolation between A and B.

Unreal’s string functions have a distinct Basic look and feel:

  • int Len( coerce string[255] S ); Returns the length of a string.
  • int InStr( coerce string[255] S, coerce string[255] t); Returns the offset into the first string of the second string if it exists, or -1 if not.
  • string[255] Mid ( coerce string[255] S, int i, optional int j ); Returns the middle part of the string S, starting and character i and including j characters (or all of them if j is not specified).
  • string[255] Left ( coerce string[255] S, int i ); Returns the i leftmost characters of s.
  • string[255] Right ( coerce string[255] S, int i ); Returns the i rightmost characters of s.
  • string[255] Caps ( coerce string[255] S ); Returns S converted to uppercase.

Vector functions:

  • float Size( vector A ); Returns the euclidean size of the vector (the square root of the sum of the components squared).
  • vector Normal( vector A ); Returns a vector of size 1.0, facing in the direction of the specified vector.
  • Invert ( out vector X, out vector Y, out vector Z ); Inverts a coordinate system specified by three axis vectors.
  • vector VRand ( ); Returns a uniformly distributed random vector.
  • float Dist ( vector A, vector B ); Returns the euclidean distance between two points.
  • vector MirrorVectorByNormal( vector Vect, vector Normal ); Mirrors a vector about a specified normal vector.

Advanced Language Features

ForEach and iterator functions

UnrealScript’s "foreach" command makes it easy to deal with large groups of actors, for example all of the actors in a level, or all of the actors within a certain distance of another actor. "foreach" works in conjunction with a special kind of function called an "iterator" function whose purpose is to iterate through a list of actors.

Here is a simple example of foreach:

// Display a list of all lights in the level.
function Something()
{
    local actor A;

    // Go through all actors in the level.
    log( "Lights:" );
    foreach AllActors( class ‘Actor’, A )
    {
        if( A.LightType != LT_None )
            log( A );
    }
}

The first parameter in all "foreach" commands is a constant class, which specifies what kinds of actors to search. You can use this to limit the search to, for example, all Pawns only.

The second parameter in all "foreach" commands is a variable which is assigned an actor on each iteration through the "foreach" loop.

Here are all of the iterator functions which work with "foreach".

  1. AllActors ( class BaseClass, out actor Actor, optional name MatchTag ); Iterates through all actors in the level. If you specify an optional MatchTag, only includes actors which have a "Tag" variable matching the tag you specified.
  2. ChildActors( class BaseClass, out actor Actor ); Iterates through all actors owned by this actor.
  3. BasedActors( class BaseClass, out actor Actor ); Iterates throgh all actors which are standing on this actor.
  4. TouchingActors( class BaseClass, out actor Actor ); Iterates through all actors which are touching (interpenetrating) this actor.
  5. TraceActors( class BaseClass, out actor Actor, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, optional vector Extent ); Iterates through all actors which touch a line traced from the Start point to the End point, using a box of collision extent Extent. On each iteration, HitLoc is set to the hit location, and HitNorm is set to an outward-pointing hit normal.
  6. RadiusActors( class BaseClass, out actor Actor, float Radius, optional vector Loc ); Iterates through all actors within a specified radius of the specified location (or if none is specified, this actor’s location).
  7. VisibleActors( class BaseClass, out actor Actor, optional float Radius, optional vector Loc ); Iterates through a list of all actors who are visible to the specified location (or if no location is specified, this actor’s location).

Function Calling Specifiers

In complex programming situations, you will often need to call a specific version of a function, rather than the one that’s in the current scope. To deal with these cases, UnrealScript provides the following keywords:

  • Global: Calls the most-derived global (non-state) version of the function.
  • Super: Calls the corresponding version of the function in the parent class. The function called may either be a state or non-state function depending on context.
  • Super(classname): Calls the corresponding version of the function residing in (or above) the specified class. The function called may either be a state or non-state function depending on context.

It is not valid to combine multiple calling specifiers (i.e. Super(Actor).Global.Touch).

Here are some examples of calling specifiers:

class MyClass expands Pawn;

function MyExample( actor Other )
{
    Super(Pawn).Touch( Other );
    Global.Touch( Other );
    Super.Touch( Other );
}

As an additional example, the BeginPlay() function is called when an actor is about to enter into gameplay. The BeginPlay() function is implemented in the Actor class and it contains some important functionality that needs to be executed. Now, say you want to override BeginPlay() in your new class MyClass, to add some new functionality. To do that safely, you need to call the version of BeginPlay() in the parent class:

class MyClass expands Pawn;

function BeginPlay()
{
    // Call the version of BeginPlay in the parent class (important).
    Super.BeginPlay();

    // Now do custom BeginPlay stuff.
    //...
}

Default values of variables

Accessing default values of variables

UnrealEd enables level designers to edit the "default" variables of an object's class. When a new actor is spawned of the class, all of its variables are initialized to those defaults. Sometimes, it’s useful to manually reset a variable to its default value. For example, when the player drops an inventory item, the inventory code needs to reset some of the actor’s values to its defaults. In UnrealScript, you can access the default variables of a class with the "Default." keyword. For example:

var() float Health, Stamina;
//...

// Reset some variables to their defaults.
function ResetToDefaults()
{
    // Reset health, and stamina.
    Health = Default.Health;
    Stamina = Default.Stamina;
}

Accessing default values of variables in a variable class

If you have a class reference (a variable of "class" or "class<classlimitor>" type), you can access the default properties of the class it references, without having an object of that class. This syntax works with any expression that evaluates to class type.

var class C;
var class<Pawn> PC;
Health = class'Spotlight'.default.LightBrightness; // Access the default value of LightBrightness in the Spotlight class.
Health = PC.default.Health; // Access the default value of Health in a variable class identified by PC.
Health = class<Pawn>(C).default.Health; // Access the default value of Health in a casted class expression.

Accessing static functions in a variable class: Static functions in a variable class may be called using the following syntax.

var class C;
var class<Pawn> PC;
class'SkaarjTrooper'.static.SomeFunction(); // Call a static function in a specific class.
PC.static.SomeFunction(); // Call a static function in a variable class.
class<Pawn>(C).static.SomeFunction(); // Call a static function in a casted class expression.

Advanced Technical Issues

UnrealScript binary compatibility issues

UnrealScript is designed so that classes in package files may evolve over time without breaking binary compatibility. Here, binary compatibility means "dependent binary files may be loaded and linked without error"; whether your modified code functions as designed is a separate issue. on the Specifically, the kinds of modifications when may be made safely are as follows:

  • The .uc script files in a package may be recompiled without breaking binary compatibility.
  • Adding new classes to a package.
  • Adding new functions to a class.
  • Adding new states to a class.
  • Adding new variables to a class.
  • Removing private variables from a class.

Other transformations are generally unsafe, including (but not limited to):

  • Adding new members to a struct.
  • Removing a class from a package.
  • Changing the type of any variable, function parameter, or return value.
  • Changing the number of parameters in a function.

Technical notes

Garbage collection: All objects and actors in Unreal are garbage-collected using a tree-following garbage collector similar to that of the Java VM. The Unreal garbage collector uses the UObject class’s serialization functionality to recursively figure out which other objects are referenced by each active object. As a result, object need not be explicitly deleted, because the garbage collector will eventually hunt them down when they become unreferenced. This approach has the side-effect of latent deletion of unreferenced objects; however it is far more efficient than reference counting in the case of infrequent deletion.

Unreal COM integration: Unreal’s base UObject class derives from IUnknown in anticipation of making Unreal interoperable with the Component Object Model without requiring binary changes to objects. However, Unreal is not COM-aware at the moment and the benefits of integrating Unreal with COM are not yet clear, so this project is on indefinite hold.

UnrealScript is bytecode based: UnrealScript code is compiled into a series of bytecodes similar to p-code or the Java bytecodes. This makes UnrealScript platform-neutral; this porting the client and server components of Unreal to other platforms, i.e. the Macintosh or Unix, is straightforward, and all versions can interoperate easily by executing the same scripts.

Unreal as a Virtual Machine: The Unreal engine can be regarded as a virtual machine for 3D gaming in the same way that the Java language and the built-in Java class hierarchy define a virtual machine for Web page scripting. The Unreal virtual machine is inherently portable (due to splitting out all platform-dependent code in separate modules) and expandable (due to the expandable class hierarchy). However, at this time, there are no plans to document the Unreal VM to the extent necessary for others to create independent but compatible implementations.

The UnrealScript compiler is two-pass: Unlike C++, UnrealScript is compiled in two distinct passes. In the first pass, variable, state and function definitions are parsed and remembered. In the second pass, the script code is compiled to byte codes. This enables complex script hierarchies with circular dependencies to be completely compiled and linked in two passes, without a separate link phase.

Persistent actor state: It is important to note that in Unreal, because the user can save the game at any time, the state of all actors, including their script execution state, can be saved at any time where all actors are at their lowest possible stack level. This persistence requirement is the reason behind the limitation that latent functions may only be called from state code: state code executes at the lowest possible stack level, and thus can be serialized easily. Function code may exist at any stack level, and could have (for example) C++ native functions below it on the stack, which is clearly not a situation which one could save on disk and later restore.

Unrealfiles: Unrealfiles are Unreal’s native binary file format. Unrealfiles contain an index, serialized dump of the objects in a particular Unreal package. Unrealfiles are similar to DLL’s, in that they can contain references to other objects stored in other Unrealfiles. This approach makes it possible to distribute Unreal content in predefined "packages" on the Internet, in order to reduce download time (by never downloading a particular package more than once).

Why UnrealScript does not support static variables: While C++ supports static (per class-process) variables for good reasons true to the language's low-level roots, and Java support static variables for reasons that appear to be not well thought out, such variables do not have a place in UnrealScript because of ambiguities over their scope with respect to serialization, derivation, and multiple levels: should static variables have "global" semantics, meaning that all static variables in all active Unreal levels have the same value? Should they be per package? Should they be per level? If so, how are they serialized -- with the class in its .u file, or with the level in its .unr file? Are they unique per base class, or do derived versions of classes have their own values of static variables? In UnrealScript, we sidestep the problem by not defining static variables as a language feature, and leaving it up to programmers to manage static-like and global-like variables by creating classes to contain them and exposing them in actual objects. If you want to have variables that are accessible per-level, you can create a new class to contain those variables and assure they are serialized with the level. This way, there is no ambiguity. For examples of classes that serve this kind of purpose, see LevelInfo and GameInfo.

UnrealScript programming strategy

Here I want to cover a few topics on how to write UnrealScript code effectively, and take advantage of UnrealScript’s strengths while avoiding the pitfalls.

  • UnrealScript is a slow language compared to C/C++. A typical C++ program runs at about 50 million base language instructions per second, while UnrealScript runs at about 2.5 million - a 20X performance hit. The programming philosophy behind all of our own script writing is this: Write scripts that are almost always idle. In other words, use UnrealScript only to handle the "interesting" events that you want to customize, not the rote tasks, like basic movement, which Unreal’s physics code can handle for you. For example, when writing a projectile script, you typically write a HitWall(), Bounce(), and Touch() function describing what to do when key events happen. Thus 95% of the time, your projectile script isn’t executing any code, and is just waiting for the physics code to notify it of an event. This is inherently very efficient. In our typical level, even though UnrealScript is comparably much slower than C++, UnrealScript execution time averages 5-10% of CPU time.
  • Exploit latent functions (like FinishAnim and Sleep) as much as possible. By basing the flow of your script execution on them, you are creating animation-driven or time-driven code, which is fairy efficient in UnrealScript.
  • Keep an eye on the Unreal log while you’re testing your scripts. The UnrealScript runtime often generates useful warnings in the log that notify you of nonfatal problems that are occuring.
  • Be wary of code that can cause infinite recursion. For example, the "Move" command moves the actor and calls your Bump() function if you hit something. Therefore, if you use a Move command within a Bump function, you run the risk of recursing forever. Be careful. Infinite recursion and infinite looping are the two error conditions which UnrealScript doesn’t handle gracefully.
  • Spawning and destroying actors are fairly expensive operations on the server side, and are even more expensive in network games, because spawns and destroys take up network bandwidth. Use them reasonably, and regard actors as "heavy weight" objects. For example, do not try to create a particle system by spawning 100 unique actors and sending them off on different trajectories using the physics code. That will be sloooow.
  • Exploit UnrealScript’s object-oriented capabilities as much as possible. Creating new functionality by overriding existing functions and states leads to clean code that is easy to modify and easy to integrate with other peoples’ work. Avoid using traditional C techniques, like doing a switch() statement based on the class of an actor or the state, because code like this tends to break as you add new classes and modify things.

UnrealEd Command Interface

About #exec commands

...

Supported #exec commands

...

End


Unreal Zones

Tim Sweeney
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Level Designers.
Last Updated: 01/25/02

The concept of zones

Unreal levels can be huge; many of our game levels are pushing 20,000 world polygons. At any time, the player only sees a tiny fraction of those 20,000 polygons, typically 100-200 polygons. The engine spends a significant amount of CPU time figuring out which 200 polygons, out of a potential 20,000, are visible in each scene. Unreal employs several techniques to speed up this "visible surface determination" process. Most of these techniques are automatic, requiring no designer intervention. However, one of the most powerful techniques, zoning, requires level designers to manually place invisible polygons called "zone portals" in their levels. Zones greatly accelerate the engine's visibility calculations, and they also enable designers to create many special effects that are specific to a region of space, such as ambient lighting or modified gravity.

A zone is an non-convex interior region of connected 3D space, for example a room, or a group of several complex, interconnected rooms.

By dividing your map up into zones, you gain several benefits:

  • Speed. A well-zoned level typically speeds up the engine's "visible surface determination" process by over 100% in a complex map, compared to an unzoned level.
  • Ambient lighting. Each zone can have its own ambient lighting value, which is added to the regular lighting on each surface. Ambient lights are very useful for outdoors areas, where pure black shadows are unnatural, as well as in diffuse environments where one would not expect dark shadows.
  • Reverberation. Each zone can have its own aural reverberation properties; see the audio document for more information.
  • Zone-based physics properties, such as friction and gravity.
  • Water.

Seeing zones

UnrealEd has a special mode that enables you to see your level's zones graphically, which each zone rendered in a distinct color. In UnrealEd, in the 3D viewport's menu, select "Zone/Portal view". You can also see this in the game by typing "RMODE 2" at the console.

In UnrealEd, zone portals are normally visible, and you normally can't see through them. To hide them, press the joystick button in the viewport, which turns on realtime updating of the viewport. You should only use this for previewing your architecture, as this realtime updating slows down the rest of UnrealEd's user interface.

Partitioning a level into zones

Level designers can partition their levels into zones by using special kinds of brushes, zone portals, to seal up regions of their maps and make them "water tight".

There are two tools in UnrealEd that you need to use to create zone portals:

  • The "sheet brush" tool. This is represented by the bottom brush builder icon on the toolbar, which lets you build a flat square polygon. You need to build zone portal polygons using this tool; you need to create polygons that are big enough to block the passages you are sealing up.
  • The "add special brush" tool. This is represented by the solid green square icon on the toolbar, below the "add" and "subtract" buttons, which enables you to add a polygon to the world with special properties to it. When you click on the "add special brush" tool, a little dialog box comes up with several pull-down options. Choose the "Zone Portal" pulldown option. Then position your sheet brush and click "add" when you're ready to add the portal.

To zone your map, first you add a bunch of portal polygons (using the "sheet brush" tool to build them, and the "add special brush" tool to add them). Next, bring up the "rebuilder" dialog and rebuild you map. The rebuilder will go through your map and detect regions of space which are sealed up "water-tight" and assign a unique zone to each region. You can go into the "Zone/Portal" view to verify, graphically, that your level is properly zoned.

If, in Zone/Portal view, you see that the engine hasn't recognized your zones, you have probably not made the portals "water tight". You need to add in enough portals that the separate zones are completely sealed-off from each other.

If, in the game, you see "hall of mirror" effects where you placed portals, make sure your portals completely seal up the regions of space they separate. If you have a portal that only partially fills up a passageway, you might see through it into nothingness.

Where to place zone portals

For special effects zones like water zones you will, of course, place the portals wherever you need the effect.

For zones whose purpose is only to speed up the engine, your goal is to divide your level up into zones while introducing portals whose overall area is as small as possible. The smaller the portals, the less work the engine must do to process the portals. Therefore, we place our portals in passageways which naturally separate large areas, such as doorways and hallways. This approach causes the level to be divided up well, without adding too much portal area.

There is no benefit (and often a performance penalty) to placing portals in the middle of large rooms. These huge portals usually eat up more CPU time being processed than they save. Stick portals in doorways, hallways, and other narrow passages.

Adding ZoneInfo actors to specify zone properties

If you want to assign individual properties to a zone, such as water, ambient lighting, or reverb, you need to add a "ZoneInfo" actor to the zone. You only need to do this if you want to assign custom properties to the zone; if all you want it the speed advantage of portalization, you don't need to add ZoneInfo's.

In the class browser, expand the "Info" class and you'll see "ZoneInfo" right there. You can add the ZoneInfo actor anywhere in your zone; as long as it's in empty space and there aren't more than one ZoneInfo's in your zone, the ZoneInfo will work. For the engine to recognize your ZoneInfo actor, you need to rebuild your map again.

See the ZoneInfo property sheet for a complete list of the ZoneInfo properties. There are many cool adjustable parameters, such as friction, gravity, ambient lighting, pain, water, etc.

Water and translucent zone portals

To create a water zone, just set the ZoneInfo's bWaterZone variable to True. The Unreal physics code (in Pawn.uc and PlayerPawn.uc) automatically recognizes these water zones and transitions between walking and swimming physics modes.

To make transparent water, just select the zone portal's surface in UnrealEd, bring up the "Surface Properties" and turn its "Translucent" option on.

Caveats

  • A level can only have 64 zones. If you create more than 64 zones, the engine will merge some zones together, causing a loss of performance. This limit might be extended in the future.

End


Mod Authoring for Unreal Tournament

Brandon Reinhart
Epic Games, Inc.
brandon@epicgames.com
http://unreal.epicgames.com/

Last Updated: 12/08/99

Contents

  • Introduction
  • The Lazy Mans Guide
  • Some Advice to Start With
  • The Three Mod Types
  • A Few Things to Watch Out For
  • Getting Dirty: Setting Up Your Project
  • How to Build Your Package
  • How to Make a Mutator
  • The Anatomy of Mutator
  • Introduction to GameTypes
  • A first look at GameInfo
  • DeathMatchPlus, a specific game type
  • Adding a HUD
  • Adding a Scoreboard

Introduction

"Winds and storms, embrace us now,
Lay waste the light of day,
Open gates to darker lands
We spread our wings and fly away."
- Emperor, Alsvartr (The Oath)
Writing mods for the Unreal engine can be an extremely rewarding task. In the current state of the games industry, there is little better a way for a skilled programmer to show the world what he is capable of. This document is intended to give interested mod authors the information they need to write a successful mod for the Unreal engine. I will include technical information as well as pointers on mod development. If you work hard, you can get some fun stuff done through mod authoring.

The Lazy Man's Guide

So you want to get into UnrealScript hacking NOW NOW NOW. This is what you should do:

1. Export UnrealScript source files. Open UnrealED, set the Browser bar to Classes. Hit Export All. This dumps the UnrealScript source files to disk instantly creating your own SDK.

2. Create a package directory and hack some code. Like this:

    mkdir MyPackage
    cd MyPackage
    mkdir Classes
    cd Classes
    edit MyScriptFile.uc

3. Add your package to the EditPackages list in UnrealTournament.ini

4. Build your files with ucc. First delete your "MyPackage.u" if it exists. ucc make only rebuilds missing code packages. Then type "ucc make" from the System directory of your Unreal Tournamnt install.

Some Advice to Start With

When you begin writing a mod you should start small. Don't plan to write a Total Conversion (TC) from the very start. If you set goals that are too hard to reach, you'll get frustrated in the process of working towards them. It is much better to set a series of small goals and work to each one in turn. Start with a simple idea that could be expanded into a larger game. Always work on small, managable chunks that could each be released in their own right. If you do undertake a large project, organize your features into a release schedule. If your game is going to have 5 new weapons, make a release with 3 while your work on the others. Pace yourself and think about the long term.

Everyone is an idea man. Everybody thinks they have a revolutionary new game concept that no one else has ever thought of. Having cool ideas will rarely get you anywhere in the games industry. You have to be able to implement your ideas or provide some useful skill. This also applies to mod authoring. If you become a skilled or notable mod author, you will find people propositioning you to implement their ideas. Never join a project whose idea man or leader has no obvious development skills. Never join a project that only has a web designer. You have your own ideas. Focus on them carefully and in small chunks and you will be able to develop cool projects.

Remember that developing a mod doesn't mean much if you never release it. Scale your task list so that you can release something quickly, adding and improving features as your mod matures. If you hold back your mod until everything is perfect, you'll find yourself never releasing anything.

Now that you have your idea, you need to choose what kind of Unreal Tournament mod type is right for you. There are basically three types of mods. We'll go over each one in brief and then focus on them all individually.

The Three Mod Types

Mutators

Mutators are mini-mods. They have limited functionality as defined by the Mutator class. Mutators should follow certain rules. If you can't follow these rules, you should probably work on a GameType mod.

The first rule is that Mutators should be able to work with any other Mutator. If you write a "Vampire" mutator that allows the player to drain life from an enemy he shoots, the mutator should work well if combined with one of the Arena mutators or the No Powerups mutator. This is one of the beneficial features of the Mutator system. They slightly change (or mutate) gameplay, allowing for interesting combinations.

The second rule is that Mutators should only change gameplay in a slight fashion. Although that's a vague way of putting it, you need to try and restrict your Mutator behavior. Careful mutator design will increase the chances of your mutator working with other mods and will decrease your support effort.

The third rule is that Mutators should share resources with other Mutators. If your Mutator implements the "ModifyPlayer" function, you need to call "NextMutator.ModifyPlayer" somewhere inside your version of the function. This ensures that any Mutator on the Mutator list after your mod gets a chance to deal with the function call. Failing to do this is poor programming style.

GameTypes

GameTypes are a much larger class of mod. They do everything the Mutator can't and allow you access to a much larger range of functionality. If your idea can't be implemented within a Mutator, you should work on a GameType.

The drawback of a GameType is that it cannot be mixed with other GameTypes. For example, Capture the Flag is a GameType in Unreal Tournament. It is a wholly different style of gameplay from Assault (another GameType).

GameTypes are implemented as subclasses of the "TournamentGameInfo" class. There aren't any specific rules for GameTypes, other than some client-server issues that you should be aware of (and that we will discuss later).

Everything Else

It is possible to write a mod that doesn't change gameplay through the GameInfo or Mutator classes. These would include Player Plugin Models (PPM) or a new weapon. We'll talk about a few prime examples like Weapons and Pickups later. GameTypes will often include many new weapons, pickups, AI features, or special actors that are separate from the game rules themselves.

A Few Things to Watch Out For

This is where I'm going to put all the information that I wish someone had told me when I started writing mods for Unreal. A lot of this information may not be relevant to you until you have more experience with the engine. I spent a lot of time out on my front porch with a buddy (Sel Tremble) talking about things like replication trying to figure out exactly how it all worked. That was definitely one of the most satisfying things I have ever done. Cracking open a new game can be a very cool experience, but also a very frustrating one. Here I'll give you a couple pointers to ease your exploration.

Accessed Nones

Sooner or later these will start showing up in your log files. UnrealScript treats Accessed Nones as warnings but you should treat them as errors. Accessed Nones are easy to fix and always signal that something is wrong with your code. If you are familiar with C++ or Java, it's easy to figure out what an Accessed None is. I'll briefly explain them to people who aren't so familiar.

UnrealScript is an object oriented programming language. When you write a program in UnrealScript, you define a set of behavior for these objects to obey and how they will interact. An object has a set of properties: member variables and member functions. In order to access an object property, you need a reference to that object. Let's look at some sample code:

class MyObject expands Info;

var PlayerReplicationInfo PlayerInfo;

function PlayerReplicationInfo TestFunction()
{
    return PlayerInfo;
}
Here we have a simple object called "MyObject" that is a subclass of Info. It has two properties: a variable called PlayerInfo and a function called TestFunction. You might want to interact with this object from inside your mod. Let's say you have a reference to a MyObject inside your mod and you want to get some information from inside the PlayerInfo property. You might write code that looks like this:
class MyMod expands TournamentGameInfo;

function string GetPlayerName()
{
    local MyObject Object1;
    local string PlayerName;

    Object1 = GetMyObject();
    PlayerName = Object1.PlayerInfo.PlayerName;
    Log("The player's name is"@PlayerName);
}
In this example we call a function called GetMyObject() to get a reference to a MyObject. We then access that reference to resolve PlayerInfo ("Object1.PlayerInfo") and then access the PlayerInfo reference to resolve PlayerName ("PlayerInfo.PlayerName"). But what if there isn't a MyObject available, or a bug in GetMyObject() causes it to fail to return a MyObject? In that case, the function would return "None." None is an empty reference...a lot like a NULL pointer in C++.

If, in our example, GetMyObject() returns None, then the variable Object1 is assigned None. In the next line, we try and access Object1 to resolve the PlayerInfo reference. Uh oh....Object1 is None...it doesn't refer to anything. We can't access it, so the Unreal engine logs a warning saying the code broke: Accessed None in MyMod.GetPlayerName!

Its very easy to avoid buggy code like this. Just add a couple checks to your code and define special behavior in the case of a mistake:

class MyMod expands TournamentGameInfo;

function string GetPlayerName()
{
    local MyObject Object1;
    local string PlayerName;

    Object1 = GetMyObject();
    if ((Object1 != None) && (Object1.PlayerInfo != None))
        PlayerName = Object1.PlayerInfo.PlayerName;
    else
        PlayerName = "Unknown";
    Log("The player's name is"@PlayerName);
}
Now we are checking to see if Object1 is none and then checking to see if the PlayerInfo reference is none. "If" statements in UnrealScript use short circuit logic. That is, "If" statements are evaluated from left to right. As soon as the code encounters a statement that negates the "If", it stops evaluating. That means that if Object1 is None, the code will never evaluate the (Object1.PlayerInfo != None) statement. It knows that it doesn't matter what the rest of the statement says, the first part is false so the entire statement is false.

Accessed Nones can be especially dangerous in time critical functions like Timer and Tick. It takes a lot of time to write out an error message to the log and if your code is dumping 3000 error messages a second it can really kill performance (not to mention disk space).

Dangerous Iterators

UnrealScript implements a very useful programming tool called Iterators. An iterator is a datatype that encapsulates a list. (UnrealScript only supports list iterators, our next language will support user defined iterators). You can get an iterator and loop on it, performing an operation on every object inside the iterator. Here is an example:

local Ammo A;
foreach AllActors(class'Ammo', A)
{
    A.AmmoAmount = 999;
}
In this example we are using the AllActors function to get an Actor List iterator. We then use the foreach iterator loop to perform some behavior on every object the AllActors function returns. AllActors takes the class of the type of actor you want and a variable to put it in. AllActors will search through every actor in the current game for the objects you want. Here we are saying "set the AmmoAmount of every actor in the game to 999."

Sounds pretty cool, but lets think about it. We are searching through a list of hundreds of Actors for a small few. This isn't exactly a fast operation.

Iterators can be extremely useful if used carefully. Because they tend to be slow, you'll want to avoid performing iterations faster than a couple times a second. Never perform an AllActors iteration inside of Tick() and never perform AllActors iterations inside of other loops. (Okay, so saying NEVER is a little strict. Let's say...USE YOUR BEST JUDGEMENT...)

The most common type of AllActors search you'll work with will probably be a search for all of the PlayerReplicationInfo actors. PlayerReplicationInfo contains important information about Players that the server sends to each client. It allows each client to have an idea of the status of other playes without sending too much information. Its used to show the scores on the scoreboard and other common things.

Usually, there will only be a handful of PlayerReplicationInfo actors in the global Actor List. It doesn't really make sense to do a time consuming search for so few results. In order to simplify this common iteration, we've added a PRI array to GameReplicationInfo. Every tenth of a second, the PRIArray is updated to contain the current set of PlayerReplicationInfos. You can then do your operation of the PRIArray without having to do an AllActors call.

Other iterators are also available. Look in the Actor class definition for information. They do exactly what they sound like: TouchingActors returns touching actors, RadiusActors returns all the actors in the given radius, etc. Intelligent use of these iterators will help you keep your code fast.

The Foibles of Tracing

Wahaha. I just wanted to use the word foible.

Because the Unreal engine does not use a potentially visible set, if you want to find something in the world in a spacial sense, you'll need to perform a trace. Most of the time you'll have a good idea of where you are tracing, you just want to know whats on the other end of the line. Other times, you'll use a series of traces to get an idea of what surrounds the object in question.

My first advice is to avoid traces wherever possible. Think very hard about what you are using the trace for and try to come up with an alternate way of doing it. Traces are expensive operations that can introduce subtle slowdowns into your mod. You might have a player doing a couple traces every tick and during your testing everything is fine. What you don't realize, is that as soon as you are playing online with 15 of your buddies, those traces start to add up.

If you have to perform traces, limit their size. Shorter traces are faster than long traces. If you are designing a new Shotgun weapon for UT, for example, you might want to perform 12 traces when the weapon is fired to figure out the scatter of the gun. 12 traces is perfectly reasonable.... it's not like the player is going to be firing his shotgun 30 times a second. However, those 12 traces could get expensive if your mod uses large open levels. Its highly unlikely your shotgun is going to be very useful as a long-range weapon, so you might as well cut off its range at a certain point. It saves the engine from having to trace from one end of the map to the other in the worst case.

Using traces is ultimately a judgment call. It really only becomes a big problem when you perform a lot of traces in a single frame. Nonetheless, it's definitely something to keep your eyes on. Always think about the performance implications of code you write.

Decrypting Replication

Understanding replication is one of the most difficult aspects of writing a mod, but its utterly necessary if you plan on doing any netplay at all. Unfortunately, Tim's replication docs are not easy to understand and make some assumptions about the reader's knowledge that you may not possess. I'll try to point out the things that I learned only through trial and error.

Simulated functions are called on both the client and the server. But only if called from a simulated function. As soon as a function call breaks the simulation chain, the simulation stops. Be very aware of what you are simulating and what you are doing in simulated functions. Never add a function modifier like simulated just because you saw it in the Unreal source code somewhere else. Understand why you are adding it, know what it does. You can't possibly expect to write quality mods if you don't know what your code is doing.

Because a simulated function is called on both the client and the server you have to be particularly aware of what data you are accessing. Some object references that are available on the server might not be available on the client. For example, every Actor has a reference to the current level. Inside the level reference is a reference to the current game. You might write code that looks like this:

simulated function bool CheckTeamGame()
{
    return Level.Game.bTeamGame
}
This is a simple simulated function that returns true or false depending on whether or not the current game is a Team Game. It does this by checking the bTeamGame property of the current level's GameInfo reference. What's wrong with this picture?

The Game property of the Level reference is only valid on the server. The client doesn't know anything about the server's game object so the client will log an Accessed None. Yuck!

If you open up the script for LevelInfo, you can find a section that looks like this:

//-----------------------------------------------------------------------------
// Network replication.

replication
{
    reliable if( Role==ROLE_Authority )
        Pauser, TimeDilation, bNoCheating, bAllowFOV;
}
The replication block is a special statement that tells the Unreal engine how to deal with the properties of this object. Lets look at it closely.

First, we have a replication condition: reliable if( Role == ROLE_Authority). The first part of the condition will either be reliable or unreliable. If it says reliable, that means the engine will make sure the replicated information gets to each client safely. Because of the way the UDP protocol works, its possible for packets to get lost in transmission. Unreliable replication won't check to see if the packet arrived safely. Reliable replication has a slightly higher network overhead than unreliable replication.

The second part of the condition (Role == ROLE_Authority) tells the engine when to send the data. In this situation we are going to send the data whenever the current LevelInfo object is an Authority. To really decypher what this means you have to understand the specific role of the object in question. With a LevelInfo, the server is going to maintain the authoritative version of the object. The server tells the clients how the level is behaving, not the other way around. For our example replication block, this means that the data will be sent from the server to each client.

The other common type of condition is (Role < ROLE_Authority). This means that the engine should send the data when the current object is not an authority. Or rather, that the client should tell the server the correct information.

Finally, we see four variables listed beneath the condition. These are the variables that the statement applies to. In this situation, we have a statement saying, "If we are the server and the client has an outdated copy of these variables, then send to the client new information about Pauser, TimeDilation, bNoCheating, and bAllowFOV. Always make sure the data arrives safely."

The replication statement doesn't cover the rest of the variables in the LevelInfo. This can mean two things. Either the information is filled in by the client in C++ (in the case of TimeSeconds) or the information is never updated on the client and is completely unreliable (in the case of Game).

You don't have access to the C++ code, but you can make a couple inferences about an object's properties to help you determine whether or not a class has non-replicated properties that are filled in my C++. Look at the class declaration for LevelInfo:

class LevelInfo extends ZoneInfo
  native;
Native means "This object is declared in C++ and in UnrealScript." Native classes probably have behavior in C++ that you can't see. Only a few special classes are native.

Finally, watch out for classes that say "nativereplication" in the class declaration. This means that the "replication" block inside UnrealScript doesn't do anything and that replication is entirely defined in C++. Some network heavy objects use native replication to help with network performance.

So now you have an idea of how to avoid problems with simulated functions. Now lets look at replicated functions.

A replicated function is a function that is called from the client or the server but executed on the other side. An example of a replicated function is the "Say" function. When you hit the T key to talk to everyone in a game, you are actually executing the Say function along with whatever you said. The client takes the function and its parameters and sends it to the server for execution. The server then broadcasts your message to all the other clients.

Replicated functions are very easy to use if you remember one thing: they can't return a value. A replicated function is transmitted over the network to the other side...that takes time (approximately equal to your ping). If replicated functions were blocking (i.e.: they waited for a return value) network communication would halt.

This is obvious for anyone who thinks about it, but when you are working on your mod you might not think about it. Replicated functions return immediately. Use them to trigger behavior on the client (like special effects) or send a message (a weapon fire message to the server).

Finally, replicated functions are restricted to only a few classes. A function call on an actor can only be replicated to the player who owns that actor. A function call can only be replicated to one actor (the player who owns it); they cannot be multicast. You might use them with weapons or inventory items you make (where the function is replicated to the player who owns the item).

Okay, so that should help you get into replication....let's move on.

Don't use UnrealEd

UnrealEd is a great editor for developing levels, but probably not the best place to work on code. This is a judgment call. I use Microsoft Developer Studio as my editor and "ucc make" to compile the package files. I find the Find In Files option in Dev Studio to be very useful and the editor to be very powerful.

In addition, UnrealEd hides the default properties blocks of source files, making them only accessible through the Show Defaults option. This just sucks! To export the script files to disk, go to the script browser and hit the "Export All" button. The files will be exported to their package directories ready for you to browse.

If UnrealEd crashes with a DLL or OCX error of some sort, go to unreal.epicgames.com and click on Downloads. Download the latest Unreal Editor Fix. The current fix level is 4.

Getting Dirty: Setting Up Your Project.

Now its time to set up Unreal Tournament to build your project. First things first, you need to understand how UnrealScript uses packages.

Packages are collections of game resources. The resources can be anything, textures, sounds, music, or compiled game code. The package format is the same for all resources and multiple resource types can be mixed in a package. For the sake of sanity, Unreal Tournament splits up packages into resources. The textures directory contains packages with textures, the sounds directory contains packages with sounds and so forth. Even though these packages have different suffixes (.utx, .uax, etc) they are still the same kind of file.

You are going to be dealing with .u files, or code packages. Code packages primarily contain compiled UnrealScript, but may also contain textures and sounds that the code depends on.

UnrealScript is an object oriented language. If you aren't familiar with OO, now is a good time to take a detour and read my guide to object oriented programming. Here is the link: http://www.orangesmoothie.org/tuts/GM-OOtutorial.html. This document is fairly old, but still a good resource.

Since UnrealScript (lets call it US for short) is object oriented, you won't be editing any of the original source. This is different from Quake, where you edit the original source and then distribute a new DLL. In US, you will subclass the classes that shipped with Unreal Tournament, modifying them to suit your needs.

So lets make a package. I'm going to refer to our test package as "MyPackage" but you will want to call it the name of your mod. Where I say "MyPackage" you'll want to replace with your own package name. Make a directory in your Unreal Tournament directory called MyPackage. Underneath this directory, make a directory called Classes. The UnrealScript compiler looks in the Classes directory for source files to build.

Now, edit UnrealTournament.ini and search for EditPackages=. You'll see a
list of all the Unreal Tournament packages. Add your package to the
list:
EditPackages=Core
EditPackages=Engine
EditPackages=Editor
EditPackages=UWindow
EditPackages=Fire
EditPackages=IpDrv
EditPackages=UWeb
EditPackages=UBrowser
EditPackages=UnrealShare
EditPackages=UnrealI
EditPackages=UMenu
EditPackages=IpServer
EditPackages=Botpack
EditPackages=UTServerAdmin
EditPackages=UTMenu
EditPackages=UTBrowser
EditPackages=MyPackage

Lets take a break and figure out what all those packages are for!

Core contains fundamental unrealscript classes. You won't need to look at the stuff in here much at all. Notice that Core, like many .u files, has a related DLL. The DLL contains the C++ part of the package.

Engine is where things get interesting. You'll soon become very familiar with the classes in engine. It contains the core definitions of many classes that will be central to your mod. GameInfo describes basic game rules. PlayerPawn describes basic player behavior. Actor describes the basic behavior of UnrealScript objects.

Editor contains classes relevant to the editor. You'll never need to mess with this, unless you become a totally elite hacker.

UWindow contains the basic classes relevant to the Unreal Tournament windowing system. This is a good place to research how the system works if you want to add complex windows and menus to your mod.

Fire contains the UnrealScript interface to the "Fire Engine." The fire engine is the code that makes all the cool water and fire effects in UT.

IpDrv contains classes for putting a UDP or TCP interface into your mod. We use this for the IRC interface in the game, among other things.

UWeb contains classes for remote web administration.

UBrowser contains the core classes for the in game server browser.

UnrealShare contains all the code from the shareware version of Unreal. Nalis galore!

UnrealI contains all the code from the full version of Unreal. UnrealShare and UnrealI are included in UT because some UT code is based on classes in these packages. There is a LOT of content here you could use for your mod.

UMenu contains any menus for UT that don't depend on Botpack.

IpServer contains the GameSpy querying interface.

Botpack the soul of the new machine. Contains all of the game logic for Unreal Tournament. Tons of kick ass toys to play with. This is where a lot of your research time will be spent.

UTServerAdmin contains Unreal Tournamnt specific web admin code.

UTMenu contains UT menus that require content from Botpack.

UTBrowser contains browser code that requires content from Botpack.

Notice that the order matters here. This is the order in which the compiler will load the packages. "TournamentGameInfo" in Botpack is a GameInfo, so in order for the compiler to build that code, it needs to have Engine loaded. Your mod should go at the end of the list to benefit from all the code in the previous packages.

How You Build Your Package

Now that your package is set up, you are ready to build it. You don't have any code written yet, so lets make a very simple useless mod. This will serve as a good example of making a new GameType.

In the MyPackage/Classes directory, create a file called MyGame.uc. Put the following code inside of it:

class MyGame expands DeathMatchPlus;

defaultproperties
{
    GameName="My Game"
}
This creates a class called "MyGame" that is a subclass of DeathMatchPlus. All we are doing is changing the name of the game...pretty simple. Notice the inheritance in action. All the code that makes up DeathMatchPlus is now a part of your game type.

Save the file and change directory to System. Type 'ucc make' and watch the code burn. Pretty soon, your package will be compiled and a new MyPackage.u will be sitting in the System directory.

In order to make our new gametype show up in the menus, we have to give it a metaclass definition. Create a file in the System directory called MyPackage.int. INT files primarily contain localization information for foreign versions of the game, but they also contain extra information about the classes inside a package.

Add the following lines to your int file:

[Public]
Object=(Name=MyPackage.MyGame,Class=Class,MetaClass=Botpack.TournamentGameInfo)
Save it and exit. When UT's menus search for games to list in the Game selection window, they search all the .int files in the System directory for classes that have a MetaClass of Botapck.TournamentGameInfo. Now your game will show up on that list. Start Unreal Tournament and go to Start Practice Session. Find your game on the list. If you start it, "My Game" will show up as the game's name in the scoreboard. Cool!

So that's how you build a basic project. Obviously writing a mod is a lot more complicated than that. Now we'll get down and REALLY dirty by looking at the specifics of different types of mod.

Making a Mutator

Mutators are a great place to cut your teeth on UnrealScript because you are exposed to a limited, but powerful subset of the engine. As I said above, Mutators should only modify the game code in a relatively slight way. This increases the chances your mutator will work well when mixed with other mutators. (For example, you can play FatBoy, InstaGib, No Powerups deathmatch. A mix of 3 mutators).

All mutators descend from the Mutator base class either directly or indirectly. Let's make a Vampire mutator and see how it all works. Create a new file in your package classes directory called Vampire.uc. Drop the following code in there:

class Vampire expands Mutator;

var bool Initialized;

function PostBeginPlay()
{
    if (Initialized)
        return;
    Initialized = True;

    Level.Game.RegisterDamageMutator( Self );
}

function MutatorTakeDamage( out int ActualDamage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation,
    out Vector Momentum, name DamageType)
{
    if (InstigatedBy.IsA('Bot') || InstigatedBy.IsA('PlayerPawn'))
    {
        InstigatedBy.Health += ActualDamage;
        if (InstigatedBy.Health > 199)
            InstigatedBy.Health = 199;
    }
    if ( NextDamageMutator != None )
        NextDamageMutator.MutatorTakeDamage( ActualDamage, Victim, InstigatedBy, HitLocation, Momentum, DamageType );
}

The first line declares the class contained in this file. US is like Java in that each file contains a separate class definition. We are saying that our class, Vampire, is a Mutator. It "inherits" all the properties of Mutator.

Next, we declare a class member. In UnrealScript, all class member variables must be declared before any functions (also called methods) are declared. The var keyword tells the compiler what we are doing. Here we have a Boolean (true/false) value called Intialized.

Next we have a function called PostBeginPlay. To someone who isn't experienced with object oriented programming, we have a bit of a puzzle. This object just declares functions, it doesn't seem to have any entry point! The "entry point" is inherited. Vampire is a Mutator, so it does everything Mutators can. Mutator is an Info, Info is an Actor, and an Actor is managed by the engine. In our case, we are overriding the function PostBeginPlay. PreBeginPlay, BeginPlay, and PostBeginPlay are called on every Actor in the level when the game starts. They are used to initialize the world.

Our PostBeginPlay function starts by setting initialized to true. Notice it'll return if initialized is already true. What's the point of that? Well, the problem is that the BeginPlay suite of functions get called twice on Mutators. Unfortunately, this is somewhat unavoidable. BeginPlay and its friends are called on Actors when they are spawned and when the game starts. Mutators, unlike other actors, are spawned before the game starts...so you get two calls. The Initialized check is to prevent the rest of PostBeginPlay from being executed twice.

The second part of PostBeginPlay is called RegisterDamageMutator, a method located in the GameInfo class. Here we are accessing the "Level" property that all Actors inherit. Then we access the "Game" property of the LevelInfo class that Level points to. Finally, we call the function from that reference, passing our "Self" as the parameter.

RegisterDamageMutator is a special method that tells the GameInfo to call MutatorTakeDamage on this mutator whenever a pawn takes damage. Because pawns take a lot of damage during the course of a normal game, we don't want to call this function on every mutator, that would be slow. RegisterDamageMutator allows us to limit the calls to only a subset of mutators. (By the way, in UT pawns consist primarily of Bots and PlayerPawns).

Next we have our implementation of MutatorTakeDamage. This is the heart of our Mutator. We are making a Vampire mutator. The idea is simple: if a Pawn A does damage to another Pawn B, give the Pawn A health equal to the amount of damage. Players and bots will effectively suck life off of other players or bots.

As I mentioned above, RegisterDamageMutator is called on our mutator whenever a player takes damage from another one. The pawns in question are passed to us in the variables.

We start by making sure we are only dealing with bots and playerpawns. There are pawns that are neither bots nor players and we don't want to deal with them. InstigatedBy refers to the player who dealt the damage. We do our core logic by adding to that pawn's health life equal to the damage dealt. RegisterDamageMutator always passes in an amount of damage AFTER armor, so this is raw final damage. Finally, we don't want a player gaining so much life he becomes unkillable, so we limit the total life gain to 199 points.

To finish the function off, we call RegisterDamageMutator on the next damage mutator in the list. It is critical that you pass along method calls like this. If you fail to, damage mutators loaded after your own won't work right. There are other functions that need to be passed along, which we'll look at below.

So now you can save this file and rebuild your package. We aren't done yet, though, because the mutator won't show up in the menus without some more work. Open your package's int file and add the following line to the [Public] section:

Object=(Name=SemperFi.Vampire,Class=Class,MetaClass=Engine.Mutator,Description="Vampire,You gain life equal to the amount of damage you do to an enemy.")
When the game looks for mutators to list in the Add Mutators window, it searches all .int files for objects with a declared MetaClass of Engine.Mutator. We've also added a Description for the help bar. Now we are ready to run Unreal Tournament and load the mutator. Play around with it for a bit and you'll probably get ideas for your own mutators or ways of expanding Vampire.

The Anatomy of Mutator

So now you've had your first exposure to writing a simple UT mod. Clearly this isn't enough to shake the world or get a job in the industry. Let's take a close look at the methods inside the Mutator base class. This will give you a better idea of what you can do with them. It only scratches the surface, however, because you have the power to use a multitude of inherited functions as well as interact with other objects.

We'll skip the PostRender function for now and look at ModifyPlayer. This is called by the game whenever a pawn is respawned. It gives you a chance to modify the pawn's variables or perform some game logic on the pawn. Remember to call Super.ModifyPlayer() if you override this function. That will call the parent class' version of the function.

ScoreKill is called whenever a pawn kills another pawn. This lets you influence the score rules of the game, preventing point gains in certain situations or awarding more points in others. Remember to call Super.ScoreKill() if you override this function.

MutatedDefaultWeapon gives you an opportunity to give a different default weapon to a player that enters a game or respawns. In UT, the default weapon is the Enforcer. If you just want to change the default weapon, you don't need to override this function. Instead, just add a DefaultWeapon definition to the defaultproperties of your mutator. (See the bottom of PulseArena for an example).

You don't need to mess with MyDefaultWeapon or AddMutator.

ReplaceWith and AlwaysKeep allow you to interdict objects that the game wants to add to the world. You can replace objects on the fly with other objects as they appear. The Botpack.Arena mutators are a great example of this. They take all the weapons in a game and replace them with one other weapon. If you are adding a new weapon to the game, you might want to add an Arena mutator for it.

IsRelevant is called when the game wants to add an object to the world. You can override it with special code and return true, to keep the object, or false, to reject it. If you say false, the object will be destroyed.

Mutate is cool. It lets your mutator define new commands that player's can bind to keys. If a player binds "mutate givehealth" to a key and then uses that key, every mutator will get a mutate call with a "givehealth" parameter. Your mutator might look for this string and give the player who sent the message some extra health.

MutatorTakeDamage, as described above, is called on DamageMutators. It lets damage mutators do some kind of game logic based on a pawn taking damage. It also tells you where the pawn was hit, the type of damage, and how much force the damage imparted.

RegisterHUDMutator is used to tell the game that this mutator should get PostRender calls. PostRender passes you a Canvas every frame. You can use the Canvas to draw stuff on the HUD. Look in the Botpack.ChallengeHUD class for extensive examples of abusing the Canvas. Hehe.

The best way to learn mutators is to read the code in the mutators that ship with UT. In fact, you'll probably want to spend a lot of time just pooring over the massive amount of code that comes with the game. Trace execution paths and look at how the various classes override and interact with each other. It can be very intimidating at first, but with time you'll get more experienced with where things are and what things do. Don't be afraid to go online and ask questions either or read other mod authors code. If you spend the time it takes to learn, you will be rewarded with the ability to take on larger, more difficult projects.

Introduction to GameTypes

Where to start, where to start? This is the meat. The big bone. Now we start getting into the hard stuff. Mutators can do some cool stuff. They are pretty easy to understand and they can do a lot of things by interacting with the game. They can be mixed and matched to get even cooler effects...but they are NOT very powerful. If you want to make a new type of game (say a Jailbreak style mod) you can't do it with mutators. You need to have complete control over the game rules. That's where the GameInfo series of classes come into play.

GameInfo is a class located in Engine. It is created by the game engine and is the core of the game play rules. Unreal Tournament makes use of a series of GameInfo subclasses located in the Botpack package. TournamentGameInfo contains code that is universal to all of Unreal Tournament's game types. DeathMatchPlus contains the code for running a normal death match. TeamGamePlus contains code for team deathmatch as well as general team management code. Domination and Assault, which are subclasses of TeamGamePlus, implement those particular game types.

The first step in writing your new game type is to determine which class to subclass. If you are writing a team game, you'll want to subclass TeamGamePlus. If you are writing a game without teams, use DeathMatchPlus. If you are writing a game that departs significantly from any previously styled game type, use TournamentGameInfo. Subclassing is very beneficial...you immediately inherit all of the code in your parent classes.

Lets look at a very simple Game Type mod:

class MyGame expands DeathMatchPlus;
defaultproperties
{
   GameName="My Game"
}

The above code, when saved in a file called "MyGame.uc" will build a new game type. The only difference here is that we've changed the name to "My Game." This new name will be reflected in many places: the Practice Session selection window, the Scoreboard header, and so forth. If you play this game, it'll play just like DeathMatchPlus...we haven't actually added any new behavior.

Like Mutators, we need to do a little INT file hacking in order to get the new game type to show up in the menus. Edit your package's INT file and add the following lines to the [Public] section:

Object=(Name=MyPackage.MyGame,Class=Class,MetaClass=Botpack.TournamentGameInfo)
Preferences=(Caption="My Game",Parent="Game Types",Class=MyPackage.MyGame,Immediate=True)

The practice session and start server menus look in all INT files for declared objects that have a MetaClass of Botpack.TournamentGameInfo. If you add these line to your package's INT file, you'll get an entry called "My Game" in the list of games. The name is taken from the GameName variable of your GameInfo class. The Preferences line gives your game a configuration entry in the Advanced Options menu. You probably don't need to worry about that right now.

So now we have a simple game to start messing with. What do we do? Well lets look at a few of the methods available in GameInfo. Remember, you'll need to do a lot of research on your own. You'll only become a strong UnrealScript hacker if you spend time to acquaint yourself with the code at your fingertips.

A First Look at GameInfo

Open the Engine package file "GameInfo.uc." This is the definition of the basic game logic. At the top of the file you'll see a long list of variable declarations. Many of these variables have comments that describe their purpose. Below the variable declarations come the functions (or methods) that do the work.

The first thing to look at is the Timer function. In GameInfo its pretty short, but in DeathMatchPlus its very long. Timer is a special UnrealScript event. If you call the function SetTimer(int Time, bool bLoop) you can set up a repeating timer on your actor. The Time parameter describes when the Timer function should be called. The bLoop parameter describes whether or not Timer should be called in a loop after the first call. All TournamentGameInfo classes use a Timer loop of one second. This means that the Timer function is called every second. You can use Timer for events that have to happen at certain times. By declaring watch variables that count up seconds, you can perform events at any time up to a second's resolution. DeathMatchPlus uses this to check and see if the TimeLimit has been hit in a game.

Another important time function to get to know is Tick. Tick isn't used in GameInfo, but any Actor can use it. The declaration for Tick is: Tick(float DeltaTime). Tick is called on every Actor in the game each frame. DeltaTime contains the amount of time that has passed since the last Tick. Using Tick, you can perform behavior that has to be done at less-than-a-second resolution. You must be careful not to perform CPU heavy behavior in Tick, because it is called so often.

Scroll down in GameInfo until you find the Login function. This function is called by the engine whenever a player logs in to the game. GameInfo's version of login does important setup stuff like assigning the player a name, a skin, a mesh and so forth. It also spawns the intial teleport effect and finds a spawn point to stick the player at. A little ways below Login is Logout. It is called whenever a player leaves the game. You can use logout to clean up after a player exits.

Another interesting function in GameInfo is AddDefaultInventory. This function assigns a player his initial weapon and equipment. In UnrealTournment's DeathMatchPlus, the player is given an ImpactHammer and an Enforcer. LastManStanding has a great example of doing cool things with AddDefaultInventory. It gives the player every weapon in the game (except for the Redeemer) as well as some armor and a lot of ammo. You can use AddDefaultInventory to add custom inventory to players that join your mod (for example, you might want to give them a grenade and some money).

The FindPlayerStart method searches the actors in a level for NavigationPoints suitable for spawning. The "PlayerStart" actor that a map designer adds to their map is one such location. In TeamGamePlus, FindPlayerStart spawns players and bots depending on their Team. It checks the Team of each playerstart and the Team of the pawn to be spawned. You can use FindPlayerStart to write custom spawn code (for example, you might want to spawn Terrorists in one location and Snipers in another).

The RestartPlayer method is called whenever a player respawns. The basic GameInfo version calls FindPlayerStart to find a starting spot, moves the player to that spot and spawns a teleport effect. It also restores the players health, sets the player's collision, and gives the player his default inventory.

The Killed method is very useful. It is called whenever a player kills another player. It looks at the cirumstances of the death (whether a player suicided or killed successfully) and the type of damage and prints a message. It also logs the event to the ngStats log. Finally, it calls ScoreKill.

ScoreKill awards points for a kill. DeathMatchPlus assigns a frag for a successful kill and subtracts one for a suicide. TeamGamePlus also adds a point to the TeamInfo of the Killer's team, or subtracts one in the case of a suicide.

DiscardInventory is called whenever a player dies or is removed from the game. DiscardInventory goes through a pawn's inventory, tossing out weapons and destroying others as appropriate. You might override this function if you wanted to toss out a backpack or a trap.

Finally, the EndGame function is called with a reason whenever the game ends. You might want to perform special logging or clean up here.

So thats a quick look at the more important GameInfo functions. The advanced GameInfo classes like DeathMatchPlus add important new behavior for controlling bots and single player games, as well as refining the GameInfo methods into specific rules. We'll look at DeathMatchPlus next.

DeathMatchPlus, a specific game type.

Adding a Heads Up Display

Notice the GameInfo variable HUDType. This is used to specify the type of HUD the player will be given if they play your game. DeathMatchPlus uses a HUDType of Botpack.ChallengeHUD. The ChallengeHUD class is the primary HUD for Unreal Tournament. Let's take a look at adding custom HUD elements.

First, create a subclass of ChallengeHUD. Lets call it MyHUD:

class MyHUD extends ChallengeHUD;

Now add MyHUD to your gametype's HUDType. In the defaultproperties set MyHUD equal to class'MyPackage.MyHUD' Remember, you can't see defaultproperties if you are editing UnrealScript from UnrealED. Make sure you've exported the source classes and are editing using your own text editor like CoolEdit or MS Dev Studio.

A HUD does all of its drawing in the PostRender function. PostRender is called after the world has been drawn and all the models in the world have been drawn. The function passes you a canvas, which is an object that is used as an interface to the player's screen. Add a PostRender function to MyHUD:

function PostRender(canvas C)
{
    Super.PostRender(C);
}

What does the Super call do? It calls the parent class version of PostRender. MyHUD's parent class is ChallengeHUD, so that version of PostRender is called. If you add your custom code after the call to Super.PostRender, you'll be able to add elements to the HUD that will draw on top of all the other HUD elements. If you don't call Super.PostRender all of the basic HUD elements like weapon readouts and so forth will not be drawn.

The Canvas class is defined in the Engine package. You might want to open it up and get a look at its member functions. The ChallengeHUD class is full of good examples on how to draw stuff to the HUD. As an example, lets just draw the player's name on the HUD:

function PostRender(canvas C)
{
    Super.PostRender(C);
    C.SetPos( 0, Canvas.ClipY/2 );
    C.DrawColor.R = 255;
    C.DrawColor.G = 0;
    C.DrawColor.B = 0;
    C.Font = MyFonts.GetBigFont( C.ClipX );
    C.DrawText( PlayerOwner.PlayerReplicationInfo.PlayerName, False );
}

This code sets the canvas drawing position to halfway down the screen and all the way to the left. Next, it sets the drawing color to be a deep red. It then asks MyFonts (the ChallengeHUD font info object) to return an appropriate big font. The font size returned depends on the screen's resolution, so we have to tell the FontInfo class what the X length of the screen is. Finally, we draw the player's name.

Your HUD can be much more complex...adding scrolling features and new types of information readouts. You'll want to look over ChallengeHUD's PostRender function and see how it gets information about the world from PlayerOwner and other related objects. Skillfully changing the HUD can add a whole new look and feel to your modification.

Adding a Scoreboard

Scoreboards work just like HUDs. If you create a new scoreboard class that extends TournamentScoreboard and put the class in your gametype's ScoreBoardType variable, players will be given a scoreboard of that kind. A scoreboard draws its information whenever the Player's bShowScores variable is true. It draws through the PostRender function and is given a Canvas parameter. Look at TournamentScoreboard for an example of player sorting and score listing.

Pickups

Coming soon.

Weapons

Coming soon.


The Dusty Tome of UnrealScript Black Magic

Brandon Reinhart
Epic Games, Inc.
brandon@epicgames.com
http://unreal.epicgames.com/

Last Updated: 12/08/99

I. Introduction

UnrealScript is a powerful programming language, but one steeped in the shrouded mystery of time. The purpose of this document is to reveal some of the more arcane methods of invoking this language. The tips and guides in this document will be compiled over time, from the author's one experience and from the experience of those who submit entries. For now, entries will be unsorted.

II. Index to Invocations

  • Using UWindow for Mutator Options
  • Using SpawnNotify to control object creation.
  • Using Entry for persistent object creation.
  • Package flags for package control.
  • Setting Package flags directly: ucc packageflag.
  • Using MS Developer Studio as an UnrealScript IDE.
  • Using BatchExport

III. UnrealScript Spellcraft

Using UWindow for Mutator Options

Author: Jack 'Mek' Porter
Email: jack@epicgames.com
Mutators with configuration options should make their own UWindow subclasses for configuration, and insert themselves into the (usually invisible) Mods menu, instead of using advanced options. Code examples of this can be found here: http://www.planetunreal.com/mutation/tutorials/mekoptions.html.

Using SpawnNotify to control object creation.

Author: Brandon 'GreenMarine' Reinhart
Email: brandon@epicgames.com
The SpawnNotify actor can be used to intercept and replace actors as they are instantiated. To do this subclass the SpawnNotify actor. In the default properties, set the ActorClass variable to the class of the actor you want to intercept. In the SpawnNotification method, destroy the actor that is passed in the parameter and spawn your new actor instead. This can be used to implement a custom PlayerReplicationInfo:

class MyPRISpawnNotify expands SpawnNotify;
event Actor SpawnNotification( Actor A )
{
    if (!A.IsA('MyPlayerReplicationInfo'))
    {
        A.Destroy;
        return Spawn(class'MyPlayerReplicationInfo');
    } else
        return A;
}
defaultproperties
{
    ActorClass=class'PlayerReplicatonInfo'
}

When you spawn your SpawnNotify object it will add itself to the level's SpawnNotify list. Objects in that list are queried with SpawnNotification whenever an object of their ActorClass is created. Notice that the example is careful to check the type of the actor. Failing to do this would cause an infinite loop (as our spawn notification destroyed the MyPlayerReplicationInfo it tried to create).

Using Entry for persistent object creation.

Author: Mongo
Email: mongo@planetunreal.com
Most UnrealScript objects are garbage collected when the level changes. If you have an object you need to be persistent across a level change, spawn it inside the 'Entry' level. The Unreal engine always has a small level loaded that exists for the lifetime of a game session, the 'Entry' level. Objects that are loaded inside of this level will not be garbage collected when the main level is destroyed. The UWindow system provides a method called GetEntryLevel() that I use inside the DecalStay mutator. Be very careful with this, however. If your persistent object references other objects in the main level, those objects will not be garbage collected. This can lead to very subtle and dangerous bugs.

Package flags for package control.

Author: Brandon 'GreenMarine' Reinhart
Email: brandon@epicgames.com
Every package has a set of three flags that can be controlled by a mod author. In order to set these flags, you need to be using 'ucc make' to compile your package. In the package's classes directory create a file called "MyPackage.upkg" where MyPackage is the name of the package. Put the following stuff in that file:

[Flags]
AllowDownload=False
ClientOptional=False
ServerSideOnly=False

When you rebuild your package, the settings you give each of these flags will be saved. AllowDownload will send your package to clients that connect to a server with that package set as a ServerPackage. ClientOptional means that the client doesn't have to have the package in order to connect to the server. A client optional package can be skipped during auto download and the client will still be allowed to connect. ServerSideOnly indicates whether or not the package should be loaded on the client side when a client joins a server running the package.

Client side mods that add new graphics or sounds will want to turn off ServerSideOnly and turn off ClientOptional. Server side mods will want to turn on ServerSideOnly and turn on ClientOptional.

Setting Package flags directly: ucc packageflag

Author: Jack 'Mek' Porter
Email: jack@epicgames.com
It is possible to set packageflags on compiled packages using the 'ucc packageflag' commandlet. Individual packageflags can be added or removed, type 'ucc help packageflag' for information.

Using MS Developer Studio as an UnrealScript IDE.

Author: Brandon 'GreenMarine' Reinhart
Email: brandon@epicgames.com
With just a little bit of work you can set up Microsoft Developer Studio as an UnrealScript development environment. The first thing to do is export the UnrealScript source files. Start UnrealED and switch the browser bar to "Classes." Hit the Export All button to export the source files to disk.

Now start DevStu and create a new workspace in your Unreal Tournament directory. Add an empty windows DLL project for each source package (Core, Engine, Botpack, etc) and create a folder until the FileView called Classes. Set the folder's extension type to uc. Finally add each package's source files to their respective folder.

You can compile inside DevStu by using a custom batch file. Create a MakePackage.bat inside your UnrealTournament system directory and add some commands like this:

@ECHO OFF
del %1
ucc make

This will rebuild the argument (for example, MakePackage Wookie.u would delete Wookie.u and rebuild it). Now add a custom tool to the tools list in DevStudio. If you select "Use Output Window" the results of the build will be dumped to the Build window in Dev Studio. Finally, you can attach your custom tool to a custom button and put it on your button bar for fast access.

If you want limited context highlighting, you can run regedit and find the following key:

[HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Text Editor\Tabs/Language Settings\C/C++]

Add "uc" to the FileExtensions list. Make sure DevStudio is shutdown first, otherwise it'll write over your changes when you exit. Now restart DevStudio and you've got some limited context highlighting for UnrealScript!

Using BatchExport

Author: Nathaniel "^Soul^" Brown
Email: Soul@PlanetUnreal.com

UCC has many commandlets which are interfaces from UCC to Unreal. They are defined in Object->Commandlet. They can be scripted(such as Object->Commandlet->HelloWorldCommandlet) or done in C++, the later of which gives you better access to unreal and its package format. One of the more useful commandlets is BatchExport. BatchExport allows you to export all files of a specific type from a .u, .uax, .umx, and .utx. From the command prompt you just type 'ucc.exe batchexport 'Item type' 'File Extension 'path''. The valid types are 'Class', 'Sound', 'Texture', and 'Music'. So say for instance you wanted to export all the class files out of botpack.u without opening UnrealED, you would go to the command prompt and type 'ucc batchexport botpack.u class uc x:\tournament\botpack'.


IpServer Package for Unreal v1

IpServer Package for Unreal v1.0

Brandon Reinhart
Epic MegaGames, Inc
brandon@epicgames.com
http://www.epicgames.com/

Audience:

  1. UnrealScript Programmers and Unreal Technology Licensees.
  2. Programmers developing third party information gathering tools.
  3. Server administrators interested in creating a master server uplink.
Last Updated: 09/14/98

References to Unreal's C++ code is only relevant to Unreal licensees who have access to Unreal source.

Overview

"I don't know what to do. I need a rendezvous."
- Kraftwerk, Computer Love
Communication with other servers and systems is integral to the online gaming environment. Applications like GameSpy, QStat, and PingTool allow players a simple central application from which to manage the massive numbers of servers world wide. In addition, as games become more mature and bandwidth more available, the ability to link multiple servers in a network becomes more attractive.

The IpServer package for Unreal is provided for programmers interested in communicating with the Unreal game server, or programmers interested in expanding the information available through such communication. IpServer makes the underlying UDP architecture more or less transparent and allows an easy interface for communicating to external systems.

One of the goals in developing the IpServer query interface was to harness the power of Unreal's object oriented architecture. As such, it is possible to query for nearly any game, level, or player information Unreal or Unreal derivatives provide.

Another goal was to make integration with existing programs as easy as possible. IpServer is completely compliant with GameSpy's new query protocol. A copy of the GameSpy development docs can be obtained from Mark Surfas (mark@gamespy.com), but the majority of the protocol, as is relevant for communicating with Unreal, is documented here.

TCP & The Old Stuff

The IpDrv package has been broken up into IpDrv and IpServer. IpServer, documented here, contains all classes relevant for performing server uplinks and queries.

The old TCP versions of the Uplink and Query classes have been removed.

Master Server Uplinks with UdpServerUplink

UdpServerUplink and UdpServerQuery are the two classes in IpServer that handle master server uplinks and application queries, respectively. UdpServerUplink is instantiated when a server begins and if that server is configured for a master server uplink, it initializes the uplink and instantiates a UdpServerQuery class.

The first step in setting up the master server uplink is to configure the server. To do this, start Unreal, open the menu and go to Options::Advanced Options. A small config window will pop up. Inside the window, click on "Networking" then click on "Master Server Uplink Config" It will take a few seconds for the IpServer class to load. When the class is loaded, the menu will expand allowing you to set the following options:

DoUplink [true/false]
If DoUplink is true, then Unreal will attempt to connect to the master server. If false, it will not. Note that you must attempt to connect to a master server in order for the game server to answer queries. This can be changed by overriding the PostBeginPlay() function in UdpServerUplink.
Default: false

MasterServerAddress [IP Address/Domain Name]
This is the internet address of the master server. It can be specified as either a fully qualified domain name or as a dotted IP address. If empty, the default master server for the game server's region will be used.
Default: none

MasterServerPort [integer port num]
This is the port that the master server is listening for heartbeats on. For GameSpy, the master server listen port is 27900.
Default: 27900

QueryPort [integer port num]
This is the port that the game server will listen for queries on.
Default: 8777

UpdateMinutes [integer time in minutes]
This is the period of time, in minutes, that the game server will send a heartbeat packet to the master server. For GameSpy this should be 5 minutes.
Default: 5

UplinkPort [integer port num]
This is the port that the game server will bind for sending heartbeat packets to the master server. Specifiying 0 means that you do not have a port preference. A free port will then be assigned.
Default: 0

Region [int RegionCode]
This is a GameSpy code for the game server's geographical region. The default master server is also determined from this value.
Valid codes are:

0 - No Region Specified (any Region)
1 - Southeast US
2 - Western US
3 - Midwest US
4 - Northwest US, West Canada
5 - Northeast US, East Canada
6 - United Kingdom
7 - Continental Europe
8 - Central Asia, Middle East
9 - Southeast Asia, Pacific
10 - Africa
11 - Australia / NZ / Pacific
12 - Central, South America

Default: 0

Once you have configured the above options as you see fit, you are ready to start your game server. The UdpServerUplink package is automatically loaded whenever a new game server starts, so once the uplink is configured the work is done.

On the implementation side of things, UdpServerUplink is intentionally very simple. When PostBeginPlay() is called on the uplink object, it binds all appropriate ports, creates the query object, and sends out an initial heartbeat. It also sets up a timer to send heartbeat packets every UpdateMinutes * 60 seconds.

Query Service with UdpServerQuery

The core of the IpServer package is the UdpServerQuery class. When instantiated, a UdpServerQuery will listen for GameSpy Query Protocol formatted queries and respond with game information. If the game server is configured to perform a master server uplink then a query object will be spawned at the time the uplink is initialized.

Like UdpServerUplink, UdpServerQuery requires configuration prior to use. Go to the "Networking" menu as before and click on "Game Server Query" to open the configuration window. The following options are available:

AdminEmail [string 128]
This is a string identifying the email address of the game server administrator. If nothing is supplied, then nothing will be sent to the master server.
Default: none

AdminName [string 128]
This is a string identifying the organization or person running the game server. If nothing is supplied, then nothing will be sent to the master server.
Default: none

ServerName [string 128]
A name for the server. This can be anything.
Default: Another Unreal Server

ServerPort [int port num]
The port the server is running a game on.
Default: 7777
As the IpServer package develops, more user definable strings will come available. Feel free to email me with suggestions for new strings. I will not, however, be including the suggested AdminAge, AdminSex, and AdminPhoneNumber. :-)

Once the query responses are configured the setup is finished, just run a server to have the query server object answer queries.

Inside UdpServerQuery

Internally, UdpServerQuery is very simple. It binds all appropriate ports in the BeginPlay() function, which is called when the object is instantiated.

Once initialized, the UdpServerQuery is entirely event driven. It reponds to ReceivedText() events which are triggered whenever a query packet it received on the listen port.

The intercepted string is recursively parsed and answered in the ParseQuery function:

function string[240] ParseQuery(IpAddr Addr, string[240] Query, int QueryNum, out int PacketNum)

Query is the received string query. QueryNum and PacketNum are used for numbering response packets. Addr is the address of origin for the query.

ParseQuery is pretty straightforward. The intrinsic function ParseNextQuery takes a GameSpy querystring and parses out the first \key\optional_value pair. A success indicator is returned. QueryType contains the key, QueryValue contains the value, if any, QueryRest contains the remainder of the Query, and FinalPacket indicates whether the sectioned parsed is the last valid \key\optional_value pair in the Query. This is easier to understand if you know how the GameSpy Query Protocol works. (So I will briefly digress.)

--BEGIN DIGRESSION--

Each query is a series of \key\optional_value pairs. A simple query might look like:

\basic\

or

\echo\What time is it, foo?

A compound query might look like:

\basic\\info\\echo\What time is it, foo?\\players\

In the first case, ParseNextQuery() would return true. QueryType would contain "basic", QueryValue would be a null string, QueryRest would be a null string, and final packet would be true.

In the last case, ParseNextQuery() would return true. QueryType would contain "basic", QueryValue would be a null string, QueryRest would contain "\info\\echo\What time is it, foo?\\players\", and final packet would be false.

If valid strings are sent with abnormal leading or trailing characters, the abnormal characters will be ignored and discarded. For example, the query:

junkjunkjunk\basic\morestuffthat'sjunk

Would be parsed by ParseNextQuery() just like the query \basic\.

--END DIGRESSION--

If ParseNextQuery returns successfully, the path of execution switches on the QueryType. Here are possible valid queries:

\basic\
The basic query obtains the game name, game version, and server location:

\gamename\unreal
\gamever\[current version]
\location\[regional location]

The gamename is ALWAYS "unreal". This is so that querying programs can tell that the game server is, in fact, an Unreal server.

\info\
The info query obtains various important server information. Specifically, Unreal answers with:

\hostname\[server name]
\hostport\[server game port]
\hostip\[server game ip]
\mapname\[current map name]
\gametype\[current game or mod name]
\numplayers\[number of players]
\maxplayers\[max number of players]
\gamemode\openplaying

The gamemode is ALWAYS openplaying. This is to tell querying programs that the Unreal server's game can be dynamically joined. Obviously there aren't any carriage returns in the actual answer string.

\rules\
The rules query obtains rules for the current game. Specifically, Unreal answers with:

\timelimit\[time limit]
\fraglimit\[frag limit]
\MultiplayerBots\[true/false]
\ChangeLevels\[true/false]
\AdminName\[string name] *optional*
\AdminEMail\[string email] *optional*

Optional strings aren't sent if the answer would be null.

\players\
Players is used to obtain specific information on all connected players:

\name_N\[name of player N]
\score_N\[score of player N]
\team_N\[team of player N]
\skin_N\[skin of player N]
\mesh_N\[mesh of player N]

Ping and Time Playing will be added in the future. See below for more information on this response and its structure.

\status\
Status is a special query that obtains all the results of the basic, info, rules, and players queries combined.

\echo\echo_string
The echo query obtains a response that is identical:

\echo\echo_string

\secure\challenge_string
The secure query is used to verify that the server being queried is actually a legit Unreal server. The challenge_string is encrypted using a secret key and sent back:

\validate\response_string

\level_property\propname
A special query that is not in the GameSpy Query Protocol specification. This is discussed below, but the response is of the form:

\level_propname\propvalue

\game_property\propname
A special query that is not in the GameSpy Query Protocol specification. This is discussed below, but the response is of the form:

\game_propname\propvalue

\player_property\propname
A special query that is not in the GameSpy Query Protocol specification. This is discussed below, but the response is of the form:

\player_propname_N\propvalue

In addition, each packet is sent with an identifying number appended to the end:

\queryid\querynum_packetnum

Each query is assigned a unique identifier called the querynum. If the response to the query is broken up over multiple packets, each packet is numbered with a packetnum value. This is because the UDP protocol does not guarantee that packets will arrive in order. This system is detailed further in GameSpy's Query Protocol Documentation.
Example:

A client queries with \basic\ and the answer packet as \queryid\1_1 appended to the end. Another client queries with \status\ but the response is broken into multiple packets with the trailers \queryid\2_1 \queryid\2_2 \queryid\2_3 and so on.

Finally, the last packet in each response has the tag \final\ appended to it just before the \queryid\ tag. This is so that the querying application can determine how many packets are in the response.

UDP Issues and Packets

I have chosen to implement as much of IpServer in UnrealScript as possible. The idea is to make a server uplink/query system that is very extendable by third party developers and mod authors. As such, while the number of transferred packets is generally minimal, it may not always be optimal.

Here are some things to keep in mind about using IpServer:

  • UDP is an "unreliable" protocol. It doesn't check to see if packets have arrived at their destination and it doesn't resend packets that are lost.
  • UDP doesn't guarantee packet order. If you send data to another machine in seperate packets, those packets may not arrive in the order sent. Using a numbering system, like the \queryid\X_X system, to manage packet arrival.

The Property Queries

At this time, UdpServerQuery is capable of responding to three unique queries. Called the property queries, these queries allow the requesing server to obtain arbitrary member variables from certain game objects. The queries are:

\level_property\name of member variable
This query obtains a member variable from the server's current Level object.

\level_propname\propvalue

\game_property\name of member variable
This query obtains a member variable from the server's current Game object. The default behavior is to cast the Level.Game reference as a DeathMatchGame, so unmodified servers can only send members of DeathMatchGame.

\game_propname\propvalue

\player_property\name of member variable
This query obtains a member variable from each connected player's PlayerPawn.

\player_propname_N\propvalue of player N

Using the GetPropertyText method Unreal's object class provides, these queries can be used to obtain ANY non private information from the relevant objects. This can be of great use to query application authors who need information not provided by default responses but who don't want to subclass a new query server.

On the other end of the spectrum, UnrealScript programmers who are making their own mods can subclass the query server and, for example, cast the Level.Game reference as their own game type. Thus providing querying applications the ability to obtain special game information specific to the new mod.

Programmers could also take the provided Property Queries as examples to derive their own. For example, you could make an Actor property query that would use the AllActors iterator to obtain information on literally ANY actor instantiated on the game server. Obviously, significant design consideration will have to be put into how best to use such dynamic power (the potential for abuse is why a general Actor query is not included in the public release).

IpServer as a Model

IpServer serves as a good model on how to use the UdpLink package effectively. Read the code and come up with ideas for your own UdpLink derivatives. Possible ideas include:

- Linked Game Servers
(use GetPropertyText to send information on Actors to other servers)
- IRC/telnet Interfaces
(use the UdpLink or TcpLink capabilities to communicate with remote machines)
- Advanced Querying Systems
(use the query model as a guide to creating a versitile query interface for your Unreal engine game or modification)

Conclusion

IpServer will be regularly updated, but could forseeably achieve a plateau of functionality where more improvements are not necessary. The potential of the Property Queries implies that Unreal could work with future versions of querying tools with little work on either end (IpServer maintainer or query tool author). The Property Queries also set up the potential for very complex and very cool interserver relationships.

END


PKG Commandlet

Left.jpg (1269 bytes) PKG Commandlet

Overview

This commandlet was written to make the creation of packages easier for people making skins and so on. What it does it it provides an easy way to export data from package and to create new packages. Currently, it works with sound and texture packages. You can download it here.

Rather than explain the command line options in depth, I'll just give some quick examples ...

Exporting Data

To export data from a texture package, you might use the following syntax (starting from the system directory) ...

"ucc pkg export texture ..\textures\starship c:\temp\starship"

What this will do is export all textures from the "starship.utx" file into the "c:\temp\starship" directory. Group names become sub directories. So you'll end up with something like the following on your hard drive...

This is the exported data from the texture package. Inside of each directory are the PCX files for the textures that were in each group. If there are no groups, then the textures would just be in the base "c:\temp\starship" directory. There is also an extra file stuck in the "c:\temp\starship" directory called "spec.ini". This file is created automatically when you use this commandlet to export the textures. It allows you to customize the importing of each texture when the time comes. A sample from this file looks like this ...

[ImportInfo]
sh_ep2=mipmap=1 masked=0
sh_spts=mipmap=1 masked=0
sh_wl1=mipmap=1 masked=0
sh_pnl3=mipmap=1 masked=0
sh_plw3=mipmap=1 masked=0
sh_grd4=mipmap=1 masked=1
sh_grd3m=mipmap=1 masked=1

This is not a complete list of course, but what you see here are the names of the textures in this texture package. After each one is a string which tells the commandlet how to import each texture. This gives you the same options as you have when importing textures via UnrealEd.

Importing Data

Importing is very similar to exporting. To import the directory structure that we exported above, we would use the command ...

"ucc pkg import texture ..\textures\MyStarship c:\temp\starship"

This will create a texture package called "MyStarship.utx" from the files found in the "c:\temp\starship" directory. It will read one sub directory deep, and use those directory names as group names. So if you use the directory that we created above, the "Base", "Ceiling", etc directories would become groups within the package.

When it imports the textures, it reads the file "spec.ini" from the base directory ... in this case "c:\temp\starship". As explained above, this file contains information about each texture and how it is to be imported. If a texture is not listed in this file, it is imported with the default settings ("mipmap=1 masked=0"). If this file is missing altogether, then ALL files are imported with the default settings.

Sound Packages

We haven't talked about sounds yet, because the procedure is exactly the same as for textures with the exception of "spec.ini". Sounds don't have any import parameters so this file is not necessary for sounds.

Advantages

Now, you might be asking, why does this commandlet exist when you can create packages with UnrealEd? Well, the simple answer is that this is easier and faster than starting up the editor and handling all the importing yourself. Importing itself isn't so bad, but exporting via the editor is a pain since each file has to be imported individually. This can take a long time.

One advantage of this is if you set up a source art (or sound) directory somewhere and put batch files in each one to create the corresponding package, then throughout development all your artists have to do to update texture packages is to put the PCX files into the proper directories, and double click the batch file. If you have questions about how any of this works, feel free to contact me at warren@epicgames.com.

- Warren

Left.jpg (1269 bytes)


Unreal ANIMATING REAL

Unreal ANIMATING REAL-TIME TEXTURES manual

Version 1.01.html (c) 1998 Erik de Neve - Epic MegaGames, Inc.

Last Updated: 06/19/98

Contents

Using Unreal A.R.T.

  • Introduction

  • Applications

  • Timing and frame rates

  • Performance and memory

Creating animating textures

  • Basics

  • Palettes and color

  • Fire textures

  • Wave textures

  • Wet textures

  • Ice textures

Using Unreal A.R.T.

Introduction

Unreal's 'Animating Real-time Textures' technology (working title 'fire engine’) enables users to create and apply realistic dynamic textures immediately from within the Unreal editor.

Applications

The real-time animating textures can be used almost anywhere in Unreal; on surfaces, moving brushes, and even actors. All of the animating real-time textures do not maintain mip-maps, which means they do not have special scaled-down versions to look good at various distances. Most effects however have a smooth appearance and scale really well even without mip-mapping.

Transparent surfaces provide one of the coolest uses for the fire and wave textures. Positioned in cross-, star- or more elaborate formations, fire can look almost volumetric. Microtextures can also benefit from animation in special cases.

The water, wet- and ice-textures can convey much more than realistic water surfaces; used as a general means of warping source art in a noisy pattern, force-fields, swirly energy bursts and convincing turbulent flames are just a few of the possibilities.

Timing and frame rates

Fire, wave-and wet-textures are updated iteratively; the new frame takes the state of the last frame as its input, and then updates the texture.

This means such textures may need some warming-up time in order to look the way they're supposed to; for this you can set the PrimeCount parameter in the texture's animation properties to an appropriate number of iterations. This does not apply to Icetextures, the speed of which can be made explicitly frame-independent - see the IceTextures chapter.

Each texture has two basic parameters that determine the update rate at game-time, as well as at editor-time: MinFrameRate and MaxFrameRate, in the Animation panel of a texture's properties window. By default, both are zero, and the texture's update code will be called whenever a new frame is rendered in the game, so it will follow the framerate of the game. The advantage of this is a consistently smooth animating effect, but this may be too fast or too slow depending on the design context.

If you specify nonzero values, the framerate at which the texture updates itself is forced to be anywhere between these two rates. As long as the framerate at game-time falls within these two limits, the resulting behavior is still one texture update each frame.

This is also useful temporarily when editing the dynamic texture in the editor on fast computers, where the rate of frame updates may be too high to get a realistic impression of in-game behavior. Regardless of these settings, a dynamic texture is never updated when it is out of view.

Fire and water textures may need some 'warming up' time to attain a stable appearance - e.g. a flame needs to fade out to fill a texture, and waves need some time to spread out. When it is essential for your level to avoid visible texture bootstrapping, you can set the PrimeCount variable to some (low) "warming-up" value, from the properties / Animation panel.

Performance and memory

Each frame of an animating texture is created in real-time. This has obvious memory benefits over storing pre-rendered sequences. While all the effects use highly optimized code, displaying scenes with a lot of different large animating textures can have some negative effect on the frame rate. However, animating textures are not updated when no part of them appears on the screen; so you can still use many (large) animating textures in a single level as long as most of them are not visible at the same time. It's also efficient to use the same texture for multiple objects, like torchflames.

Performance slowdown is directly proportional to the number of pixels in a texture, so don't use a large texture where a smaller one would suffice. If you like, play around drawing stuff on a large texture, but then re-create the final desired effect on a texture that's just big enough to encompass it. Some large, detailed, 256 by 256 pixel dynamic textures may be essential to your level design; but in other cases, try obtaining the same effect using a scaled-up or tiling smaller texture.

After the texture size itself, the second concern is the number of particle actors that make up all effects in the fire and water textures; these are a limited resource. You quickly run out of these if you use the ones that emit clouds and other stuff. Fire sparks have a special adjustable maximum limit SparksLimit. This amount of sparks is the actual space that gets allocated during game-time; by making this as small as possible after you finalize your fire design you achieve an optimal use of memory. This is not a big deal usually since each single spark or lightning bolt takes up only 8 bytes, but unless you really need it, the maximum of 8 x 8000 = 64Kbytes is best avoided.

When the number of sparks reaches the maximum limit, it forces certain spark-burst emitting types into regular feedback cycles. By adjusting the limit, you can prevent or fine-tune this effect. As fire textures are saved, all the transient sparks are erased first and only the source sparks are written to disk, regardless of the maximum spark limit.

Some effects present a bigger performance load than others; for example the lightning effects in a fire texture, and lines and clamped squares in the water textures are more expensive than most simpler drops and sparks.

Everything tiles in all directions. All stuff, sparks, drops, waves and flames that move off one side turn up at the opposite one. Animations look best if you avoid simple 'cyclic' schemes whenever possible - try to use some random moving sparks or oscillators with different frequencies, to drive home the fact the texture is being generated in real-time.

Creating animating textures

Basics

In the Unreal editor, you create a new animating texture by clicking the 'new' button in the texture browser.

Before clicking on 'Create', make sure you have the following set up correctly since it is not possible to change most of these later:

Name: Change this to a descriptive, unique name.

Package: This is the UTX package the new texture will sit in. Remember to always save the UTX using this exact same name, otherwise Unreal may not be able to find the correct textures. It is recommended to create and manage your animating textures for a level in one or more dedicated UTX packages, to avoid creating unnecessary dependencies and also because it is easy to lose them between lots of static textures.

Some types, like the 'Wet' and 'Ice' textures, refer to existing static textures; it is good practice to keep the static textures being referred to in the same dedicated UTX, again to avoid dependencies between UTX files.

Group: An optional classifier, very useful in the texture browser to display special groups of textures within a single package, e.g. 'skins', 'base', 'trim', 'floor'.

Class: Selects one of the four types available:

  • FireTexture
  • IceTexture
  • WaveTexture
  • WetTexture

Size: Choosing the proper size for a texture is essential. In most cases it's nice to experiment on a 256x256 texture, delete it and recreate your finalized effect on a smaller texture that's just big enough.

When a texture's editing window is visible, you can edit it directly using the mouse, in combination with the parameters in a special panel of that texture's properties window called FirePaint, WaterPaint, or IceLayer.

All the "FX_" drawing parameters affect what you draw when you draw it, so within any one type, for example lightning, you can draw multiple bolts on the screen with varying intensity and frequency characteristics. All other parameters affect the whole texture or certain types of sparks globally, like renderheat.

For the fire and water effects, the left mouse button draws whatever actor is the currently active type, and the right button erases. Some effect types are drawn as you move the mouse, others need consecutive mouse clicks. Erase large objects like lightning bolts or line segments by moving the mouse over the starting point and clicking the right button. Erasing the swarming spark types can be tricky, usually it is be easier to clear the texture and start again.

Palettes and color

Coolness of any fire or water depends almost entirely on the color palette. For the Fire and Wave textures, change the palette by referring to any other texture using the palette option in the texture panel of a texture's properties window. Clicking 'use current' will explicitly copy the palette data from the currently selected texture to the fire or wave texture being edited. Note that, to avoid dependencies, this behavior differs from the usual case in the texture browser, where textures which refer to other textures and/or their palettes - notably the Wet and Ice texture types - become dependent on those textures and require their presence in order to run.

Unreal's software transparency (and its texture masking in general) uses a form of masking with holes for all color 0 pixels, so generally you would use a ramped palette that fades to black at color 0. For most applications however, the palette is not limited in any way.

Fire textures

Examples of "custom clouds" and "eels" using non-trivial color palettes

The size of the flames can be tuned over a broad range using the RenderHeat slider. Two different fire algorithms exist; bRising = false produces fire that doesn't move up as much as bRising = true. The appearance of the fire effects depends heavily on these two parameters. FX_Heat determines the overall or initial brightness of most spark types. The maximum number of sparks can be adjusted using SparksLimit, for details read the above chapter on performance and memory.

It is recommended to combine sparks of different types, or the same type with different FX_xxx settings to obtain unique effects; for example fountain sparks at different angles, ramped lightning, etc. can combine to amazing scenes.

Usually FX_Frequency, FX_HorizSpeed, and FX_VertSpeed are interpreted as signed values centered around value 128 being zero; lower values move sparks at negative speeds, i.e. they move or circle in reverse directions.

The SparkType selects the effect you're drawing onto the texture. Not all of these are terribly useful, some were left in simply to facilitate backward compatibility during Unreal's development process. The following types are available:

SPARK_Burn

Simple, nonmoving sparks of random intensity. Looks best with bRising = true.

SPARK_Sparkle

Sparks with random positional jitter over an area of horizontal size FX_Size, vertical size FX_AuxSize, with intensity FX_Heat.

SPARK_Pulse

Great for pulse-trains, FX_Frequency sets the time frequency, and FX_Phase is the spatial frequency: 0=pulsed fire, use higher values for moving trains of sparks.

SPARK_Signal

Like the _Burn spark, but this has several options to customize the graininess, brightness and intensity distribution to any desired output, providing a versatile base fire effect.

FX_Frequency sets the average pattern frequency, FX_Heat determines the ratio of bright patches to dark ones, i.e. a medium setting increases the contrast of the overall effect.

SPARK_Blaze

Emits sparks in all directions.

SPARK_OzHasSpoken

Simple up-moving, fading-out sparks.

SPARK_Cone

Like _Blaze, but with gravity acting on the sparks. A nice sparse effect to put at the center of complex ramped lighting bolt scenes, for example.

SPARK_BlazeRight

SPARK_BlazeLeft

Simple eruptions to the right and left, falling down.

SPARK_Cylinder

Sparks moving in horizontal, 'cylindrical' orbits, with angular velocity FX_HorizSpeed. FX_Heat determines the minimum intensity, which always varies along a spark's orbit - this means that a low FX_Heat setting gives a collection of sparks a 3d-appearance, as if the 'backfacing' sparks are removed. FX_Size sets the amplitude of the orbits.

DrawMode influences the FX_Size dynamically; when set to any of the 'Lathe' options, as long as you keep the mouse button pressed while drawing, all sparks will be aligned around an invisible vertical axis so it's as if you're using a lathe. Lathe_2, _3 and _4 draw multiple sparks at regular spacings around the cylinder, instead of just one.

The way the initial position of sparks wind around the cylinder as you draw is influenced by FX_Frequency.

SPARK_Cylinder3d

Like the Cylinder spark, but this type makes all the 'backfaced' sparks disappear completely.

SPARK_Lissajous

FX_Size determines the amplitude of the orbits, at FX_Frequency.

FX_HorizSpeed and FX_VertSpeed determine the horizontal and vertical frequencies independently. Like the Cylinder type, individual spark intensity depends on the phase of the horizontal movement and this is always offset by FX_Heat.

SPARK_Jugglers

FX_Size sets the amplitude of these, moving on a simple vertical sine wave pattern at FX_Frequency. As with Cylinder, the 'back-facing' effect depends on the FX_Heat setting.

SPARK_Emit

Moving in the directions set by FX_HorizSpeed and FX_VertSpeed, these glow out as they progress over straight trajectories of determined by both FX_Size and the initial heat FX_Heat.

With the speeds set to extremes ( 0, 128, 255 ) the trajectories become clean straight lines.

SPARK_Fountain

Like Emit, but the sparks have gravity acting on them. A great effect for stuff like streaming lava, steam or water. Setting initial speeds to zero (128,128) makes the sparks oozing down.

SPARK_Flocks

A random moving flock of sparks drawn at FX_Heat, jittering in circular orbits of size FX_Area, with FX_Size being the lifetime of individual sparks.

SPARK_Eels

Random cloud of straight moving sparks drawn at FX_Heat with lifetime FX_Size.

SPARK_Organic

Fast moving sparks going upward at V-shaped angles.

SPARK_WanderOrganic

Wandering Organic sparks.

SPARK_RandomCloud

A wandering cloud of double-speed upward moving sparks.

SPARK_CustomCloud

Completely customizable clouds using FX_HorizSpeed and FX_VertSpeed. While moving, sparks glow up to the maximum brightness and then disappear. FX_Area determines the spark's lifetime by setting

their initial brightness; a high FX_Area value makes sparks start at a lower heat so they take longer to reach full heat. Set the speeds at or around zero (128,128) to create a nice sparkly effect.

SPARK_LocalCloud

Like CustumCloud, but the spawning points of these are random within an FX_Area sized square, the upper left corner of which is the mouse position where you draw the effect.

SPARK_Stars

Unlike any other sparks, this one doesn't get washed out by the fire algorithm, but consists of single pixels of brightness FX_Heat, which get obscured by any fire passing across it, unless the flames have a very low intensity.

SPARK_LineLightning

Click, stretch out the lightning to the desired end location, and release it. A low setting of FX_Frequency gives continuous lightning bolts, while a high setting makes it flash more intermittently. Most lightning looks coolest when it's kind of sparse, achieve this by either adjusting the RenderHeat or setting a higher FX_Frequency.

SPARK_RampLightning

Like LineLightning, but with intensity diminishing towards the endpoint of the bolt.

SPARK_SphereLightning

Spherically symmetrical lightning, with diameter FX_Size. Sparse by default, to get more coverage put a few of them on top of each other.

An example of SphereLightning

SPARK_Wheel

Sparks move outward in circular orbits the size of which is determined by FX_Area, over a path of length FX_Size. They are emitted at an initial angle PX_Phase, FX_Frequency sets the rotation speed.

SPARK_Gametes

Random cloud of straight moving sparks drawn at FX_Heat with lifetime FX_Size.

SPARK_Sprinkler

Spawns upward wavy streams, FX_Frequency determines the speed at which the initial angle changes. FX_Phase controls the relative phase. On a low FX_Heat setting, a few of these can be combined together or with other effects to design smoky whirls.

Lightning with some cone sparks at the center; some rotating cylinder sparks applied using the Lathe drawing modes to obtain a pseudo-3d look; and a swirl made with 'wheel' sparks.

Wave textures

A funky water effect using a special 2-hue palette, with some static diagonal lines creating the depressions.

The wave effect creates a pseudo-phong-shaded rendering of a physically simulated water surface.

All effects described here push, pull or clamp the height of a point or line of the surface. The default water surface level 'at rest' is 128 units high and can extend from 0 to 255. Keep this in mind when using the static effects like lines, FixedDepth and AreaClamp, which can be made (deliberately) invisible with an FX_Depth of 128.

Simply throwing in some PhaseSpots is the quickest way to get a wavy water surface, but do remember to explicitly put in some with three or more slightly different FX_Frequency values; that way, the total ripple effect never repeats and will look more random.

While some of the actual wave sources you place on a texture may look artificial, you can hide these by custom-aligning the texture on the architecture, so only the resulting waves are visible. Placing a few line segments to clamp the surface into a beveled shape can give most effects more depth. BumpMapLight defines the incident light angle in an intuitive way: moving the slider away from the middle position brings out the depth in the image, but at the same time darkens it.

BumpMapAngle defines the viewer angle, which determines the position of the highlight. PhongRange determines how much of the palette to reserve for the highlight, as opposed to regular shading. The same result could theoretically be achieved using custom palettes.

PhongSize scales the size of the highlight.WaveAmp scales the amplitude of the waves up or down at rendering time.

The DropType selects the effect you apply to the texture:

DROP_FixedDepth

Clamps a small static spot to FX_Depth.

DROP_PhaseSpot

Shakes the surface at FX_Frequency with relative phase FX_Phase. Use PhaseSpots with slightly varying frequencies placed close together to create non-repeating random looking waves.

Putting spots of the same frequency in a circle with a carefully tuned range of phases can make vortex-like waves.

DROP_ShallowSpot

Like PhaseSpot, but half as shallow.

DROP_HalfAmpl

Like PhaseSpot, but only moves below the 128-average surface level.. Useful for specific local distortions.

DROP_RandomMover

Creates jittery waves from a randomly moving position.

DROP_FixedRandomSpot

A fixed spot with random jittery output.

DROP_WhirlyThing

Moves in small circles at FX_Frequency, pushing at FX_Depth.

DROP_BigWhirly

Moves in bigger circles at FX_Frequency, pushing at FX_Depth.

DROP_HorizontalLine

DROP_VerticalLine

DROP_DiagonalLine1

DROP_DiagonalLine2

Static lines of size FX_Size, clamping the surface to FX_Depth.

When FX_Depth is 128, these provide invisible barriers to waves. At other values they create nice meniscus-like beveled surfaces, useful for matching up with features placed onto the water surface in the level. When set up right these features can stop or reflect waves on the surface in realistic ways.

DROP_HorizontalOsc

DROP_VerticalOsc

DROP_DiagonalOsc1

DROP_DiagonalOsc2

Lines of FX_Size, oscillating at FX_Frequency.

DROP_RainDrops

General-purpose raindrops. Pushes the surface to FX_Depth at a random point within in a rectangular area of size FX_Size.

DROP_AreaClamp

Clamps down a rectangle of size FX_Size to FX_Depth.

DROP_LeakyTap

Drops of FX_Depth falling at a fixed position, within a regular time interval controlled by FX_Frequency, and phase FX_Phase.

DROP_DrippyTap

Like LeakyTap, but the intervals are irregular.

Wet textures

Edit this just like the wave effect, but instead of using a palette to simulate light striking the surface, the image of the source texture is distorted by the waves, suggesting refraction. The distortion is horizontal only, which is not an issue in most cases unless your texture has large, straight horizontal features that you want to distort. Make sure you select the right texture dimensions at the start of creating a new wet-texture; unless the sizes exactly match those of the SourceTexture you want to distort, this will not work.

Small values of WaveAmp are useful for a hot-air shimmering effect. To create realistic, natural looking pools and puddles, choose an appropriate texture with enough structure on it so that distortions will be clearly visible. If the texture has dark patches on it, drawing localized water in approximately these areas will give the impression of an irregular shallow pool of clear water.

Images suggesting water or shallow depths are useful as source textures for realistic WetTexture animations.

Ice textures

A source texture, its displacement texture, and the resulting Ice texture.

Similar to the wet-texture effect, 'ice' displays a source texture with distortions, but these are taken from ‘GlassTexture’, which is interpreted as an 8-bit distortion vector field. Both the SourceTexture and GlassTexture dimensions should match the Ice texture. In the texture window, moving the mouse with the left button pressed drags the displacement 'ice layer' texture to the desired position. By setting its TimeMethod parameter to TIME_RealTimeScroll, the animation speed you see in the editor matches the in-game speed exactly regardless of the frame rate; it will skip intermediate panning positions if necessary.

Using specially constructed displacement textures, coupled with carefully tweaked panning directions, the potential range of original effects using Ice textures is enormous.Oily swirls, fluid streams spiralling around each other, and effects that look like bump-mapping are all possible.

The default setting of TIME_FrameRateSync will not give framerate-independent animations, but is still a good choice if you need smoothness, since a once-per-frame update will ensure the texture moves a little bit every frame without big skips. The MoveIce switch selects movement of either the GlassTexture or SourceTexture.

HorizPanSpeed and VertPanSpeed determine the movement in the Linear and WavyX/Y modes, with a zero-point of (128,128). Frequency and Amplitude act on the speed and size of the circular and wavy parts of a texture's movements.

There are five modes of movement. All share the linear panning speed as set by HorizPanSpeed and VertPanSpeed

SLIDE_Linear

Move a texture with speed settings HorizPanSpeed and VertPanSpeed.

SLIDE_Circular

Circular movement using Frequency, around a radius equal to Amplitude.

SLIDE_Gestation

Irregular movement using Frequency and Amplitude.

SLIDE_WavyX

A wavy horizontal movement of Frequency and Amplitude.

SLIDE_WavyY

A wavy vertical movement of Frequency and Amplitude.

Enjoy !

- Erik de Neve


Unreal Geomorph Level

Unreal Geomorph Level-Of-Detail Notes

Erik de Neve - Epic Games, Inc.

Last updated May 19 1999

LOD tech introduction

The Unreal engine has always been able to handle large open spaces quite well, but with large sized scenes, and with multi-player deathmatch and team games as well, there is an increased risk of many actors being visible at the same time.
By using distance-dependent simplification, the speed penalty for rendering actor meshes diminishes greatly as their smaller size farther away allows them to be drawn using fewer polygons.

Unreal's new continuous-LOD (Level-Of-Detail) rendering offers a way to make the rendering of all polygonal actors in the engine scaleable, fully compatible with all existing static and animating mesh content.

Polygons gradually disappear in a sequence which is fixed at content-compilation time (building the .U files) for each mesh. Such a continuous sequence of shapes, known as a 'geomorph', is constructed by automatic evaluation of the shape of a mesh, notably edge sizes and surface curvature.

Unreal's unique smooth LOD morphing ability makes the culling of polygons less conspicuous, notably close up, and is achieved by preemptive shrinkage of mesh faces in an overlapping a-synchronous fashion, while the texture mapping is smoothly adapted also.

Version 224 LOD note for licensees and mod authors

The mesh LOD as active in Unreal 224 does not give the optimal achievable speedup, as it uses very conservative default LOD strength settings. This was necessary to achieve backward compatibility with the entire Unreal 1 content without the team having to go back and check/tweak the settings for individual meshes.
There is one arbitrary hard-coded global LOD factor which licensees can change in UnMeshRnLod.h:
FLOAT MeshVertLOD = 430.f ..........
Useful settings fall between 150 and 450; smaller numbers result in more aggressive LOD culling.The MLOD console command can be helpful for testing adjustment of this global strength interactively.
The optimal tradeoff between speed and detail for individual meshes can be tweaked to satisfaction further by using the mesh LOD script parameters explained below.

 Console commands

Mainly for in-game testing purposes; to see the LOD-culling and morphing in action,set MLMODE 3, then zoom in with the sniper rifle (or directly using the FOV command) to see how the distant meshes are simplified, then fly closer in slomo+ghost mode to see it morph into full detail again.
On the UT bots, you can see the backpack appear, an antenna suddenly extends upwards, the microphone snakes its way back around the head, etc.
 Click here for some sample screenshots.

MLOD X
A strength scaling factor centered on 1.0, to scale the strength of the LOD culling -
higher values strengthen the LOD fall-off with distance.

MLMODE X
0 Draw everything at full (or at MLFIX-ed) detail.
1 Normal level-of-detail mode
2 Disable smooth morphing.
3 Ignore the field-of-view effect on LOD (great for debugging!)
4 Disable smooth morphing, ignore field-of-view.

MLFIX X
A float in the range 0.0-1.0 which, when in MLMODE 0, causes
all meshes to be drawn using this proportion of their vertices.

Mesh LOD script parameters

Here's a specific script variable example. None of these extra parameters are required.
LOD importing can be on or off by default (depending on how it is hardcoded in UnEdSrv.cpp)

#exec MESH IMPORT MESH=LodMesh ANIVFILE=MODELS\AnyMesh_a.3D DATAFILE=MODELS\AnyMesh_d.3D X=0 Y=0 Z=0 MLOD=1 LODSTYLE=0 LODFRAME=19
#exec MESH LODPARAMS MESH=LodMesh STRENGTH=1.0 MINVERTS=14 MORPH=0.25 ZDISP=90.0

MESH IMPORT parameters:

MLOD | Boolean , meshLOD switch ( if 0, the mesh will always be rendered at full detail ). Always use MLOD=0 if you want to disable any detail loss, rather than putting extreme STRENGTH or MINVERTS values in the LODPARAMS.
LODSTYLE | A bit field with switches to change the style of building the pre-collapse sequence. By default, none of these bits are set. Useful ones right now are 8 and 2 in particular. 1: Value curvature over length. 2: Protect the edges of doublesided polygons - like the CTF flags. 4: Try to respect texture seams more. Use this if there is too much 'stretching' going on. 8: Value length over curvature. Needed for unwelded, multi-element, or otherwise 'open' meshes like the new superhealth. 16: Translucent polygons will be collapsed less early in the LOD sequence. (Broken in the 224 code base.)
LODFRAME | When there are multiple animation frames, you can pick a representative one other than the default 0th frame to be sampled for generating the collapse sequence.
LODNOTEX | If set, causes texture coordinates to be ignored when importing. Results in modest memory and performance savings for complex environment-mapped meshes.
LODOLD | Maintain the original order of animation vertices as they are imported. If active, this means some internal reorganization will be done at load time, instead of compile time. Included to make differential patching of older content feasible.

MESH LODPARAMS parameters:

STRENGTH | Per-mesh linear LOD scaler. Default = 1.0. Tweak this higher for more aggressive LOD-culling, lower if you see the mesh distort too early .
MINVERTS | The minimum number of vertices you want your mesh to always retain at the farthest distances. Useful for some really simple objects (boxes, trees, birds...) that need to look good even at a fair distance.
MORPH | 0.0 for no morphing, any other value up to 1.0 indicates the proportion of vertices that are allowed to contribute to the smooth morphing. More means less popping, but at the cost of more CPU time. Useful values are 0.25 - 0.4, the default is currently 0.3.
ZDISP | In world units ( the standard player height is 60 ) this pushes away the distance at which the LOD culling kicks in. More precisely, the fraction of vertices drawn scales with the distance Z as follows: 1 / ( STRENGTH * (Z - ZDISP) ), where (Z-ZDISP) is clamped at a minimum of 1.0.


UT Skeletal Animation Notes

Contents

  • Overview
  • Exporting Animations from 3D Studio Max
  • Exporting Animations from Maya
  • Exporter Options
  • Engine Console Commands
  • General Script Commands
  • Materials
  • Log Files
  • Weapon Bone
  • Important Notes

Overview

The skeletal animation support in UT was designed to be almost completely backwards compatible with the vertex animation. This document assumes the artists/programmers are somewhat familiar with the process of creating/managing (vertex-) animation content for Unreal/Unreal Tournament (see "Animation Basics" )The animating vertices are replaced by an invisible hierarchy of animating bones, which move vertices of the mesh either directly or in weighted combinations. Content is created in 3D Studio Max 2.5/3.0/3.1 and exported to a custom (loss-less) binary format, and the animation data is digested (compressed) at package-building time.

During content rebuilds ('ucc make'), .PSA files are digested into UAnimation objects, and .PSK files into USkeletalMesh objects. The animations then work with the exact same commands and sequence-notification pathways as the classic vertex animated models.

Model files have the .PSK extension, animation files have a .PSA extension. A path name needs to be set at all times, since that also determines the destination of the log files.

A .PSK (model) file can be saved at any time when your model is loaded. The .PSA (animation) file can consist of multiple animations which are 'digested', selected animations can then be grouped together, renamed, and saved/loaded.

Animations are 'bundled' into memory as they are digested by the exporter. The actual saving out to a file is done from a separate animation manager window (see its button) which allows
saving, loading and parameter tweaking of animations in previous bundled .PSA files. Changing parameters like the animation names, grouping names, and frame rates is done on the selected animation in the first list, which can then be shuffled back and forth to the second list which represents the .PSA file to be written.

The Maya and Max exporters share the same user interfaces, but are activated differently.

Exporting Animations from 3D Studio Max

  • Download ActorX - Max 3.1 / Character Studio 2.2 compatible exporter
  • Download ActorX - Max 3.1 / Character Studio 3.x compatible exporter
  • Download ActorX - Max 4.0 / Character Studio 3.x compatible exporter
  • Download ActorX - Max 4.2 / Character Studio 3.2 compatible exporter

The exporter, ActorX is a utility plugin which you install by copying ActorX.dlu into your Max plugins folder. It can be activated in the utility pane (hammer tab-> more -> ActorX). ActorX will look for any hierarchy which has either Physique meshes or other meshes attached to it, and export either the skin + reference skeleton ('model') or the animation, using the filenames given in the main exporter utility pane.

ExampleMax contains source art for two animated meshes - Piston.max and Player.max.
The script files used to link up content into a native Unreal package are Thing.uc and Warboss.uc.
The exporter was then used to create the intermediate .PSK (skin, mesh and reference skeleton) and .PSA (animation) files. The .pcx skins are 8-bit pallettized (and where desired, downsampled) versions of the original 24-bit image files used for the Max materials. The ready-made native Unreal package containing the meshes, animations and textures is " Test.u ". Placing this in the UnrealTournament\System folder along with the standard .u files allows the engine to access the data during game runtime. If your scene contains any meshes which need to be exported as part of a hierarchy while they're not explicitly physique-linked as a skin to bones or other objects, make sure the 'all textured geometry' option in the second pane is checked.
For all meshes linked with physique, it is extremely important to initialize and set them up from the very start exactly as outlined here; otherwise there is no guarantee that results in the engine will match what you're seeing in Max.

Exporting Animations from Maya

  • Download ActorXTool - Maya 3.0 compatible exporter

  • Download ActorXTool - Maya 4.0 compatible exporter

The different windows can be called up with specific Maya/Mel commands (easily bound to custom keys by dragging the marked command text to the toolbar) :

axmain the main exporter panel
axoptions brings up the second options/script export panel
axanim starts the animation manager, which can save and load the platform-independent .psa animation files from disk, to edit the individual UT animation properties.
axbrush non-skeletal .T3D textured architecture export.

ExampleMaya.zip contains example source art in Maya 3.0 format: two simple animated meshes, Piston.mb and Worm.mb.
The script files used to link up content into a native Unreal package are Piston.uc and Worm.uc.
The exporter was used to create the intermediate .PSK (skin, mesh and reference skeleton) and .PSA (animation) files. The .pcx skins are 8-bit pallettized (and, where desired, downsampled) versions of the original 24-bit image files as used for the Maya materials. The ready-made native Unreal package containing the meshes, animations and textures is "Test.u". Placing this in the UnrealTournament\System folder along with the standard .u files allows the engine to access the data during game runtime.
Note that in Maya, there need to be actual 'Joint' objects for the exporter to recognize as a hierarchy, in contrast to the Max exporter, where any parenting of objects will do.

Exporter Options (second pane)

  • Skin selection checks ( effective for MAX exporter only )
    • All physique meshes - by default, export only mesh geometry consisting of Character Studio's Physique modifiers.
    • All textured geometry - export any textured meshes, which may be linked up by bones, or any parent/child bonds. The exporter treats these bonds like regular bones. This may also be needed when not all meshes linked to your skeleton are Physique'd.
  • Dummy culling - Checking this option makes the exporter disregard any dummy boxes which are at the ends of the hierarchy and have no effective links to any of the skin/geometry. Depending on the linkup, dummy culling can cause problems like erratic vertices and/or bones. It works OK though if you apply it after saving the skin, i.e. to the animation only.
  • Root motion lock - Check this to subtract the net root motion from an animation. 'Hard lock' will simply freeze the root node at it's frame-0 start position throughout the animation.

Engine Console Commands

These are in-game console commands that can be used to debug your meshes and animations.

  • stat anim - detailed real-time report on all animation (skeletal or regular) for meshes visible on the screen.
  • rend bone - toggles drawing of the bones when in wireframe mode.
  • rend blend - visualize the vertex-influence blending. Green vertices have single links, red ones have two, pink three, light blue four, white have five or more.
  • rend wire - enables wireframe mode in normal (lit) render modes, but is currently disabled (cheating possibilities!) so RMODE 1 is the proper way to enter wireframe mode.

General Script Commands

Animation objects are linked up with actors at runtime. Any bone names that the actor's USkeletalMesh model has in common with the linked-up animation will be animated.

Skeletal meshes are imported with the MESH MODELIMPORT command, eg:

#exec MESH MODELIMPORT MESH=SkeletalMesh MODELFILE=MODELS\SkelMesh.PSK LODSTYLE=8 X=0 Y=0 Z=0

.PSK files as generated by the Max exporter are 'Reference skin-and-skeleton' raw data chunks,
which are converted to USkeletalMeshes which define a skin, materials and UV's, bone influences, and the named bones in a reference pose.

Animation files are imported with the ANIM IMPORT command:

#exec ANIM IMPORT ANIM=AnimTest ANIMFILE=MODELS\Male.PSA IMPORTSEQS=1 COMPRESS=0.9 MAXKEYS=9999999

UAnimation objects contain named bones, (compressed), any predefined sequences, and movement tracks for each bone.

MaxKeys will put an adjustable squeeze on the number of keys in the animation as a whole;
COMPRESS= does the same but with a simple factor ranging from 0 to 1. Keys which can be interpolated most effectively are thrown out first, until we're left with the suggested number of keys (or lower, because 'perfectly' interpolatable keys are always thrown out, and all static tracks are collapsed into 1-key tracks). The initial, non-compressed number of keys in an animation always equals the (number of bones)*(number of frames) that were exported.

ImportSeqs=1 signifies that the animation sequence info embedded into the binary .PSA file by the Max exporter is to be used.

You can still specify animation sequences just like the old format, except that it's done through #exec ANIM commands and they're now tied to the animation object, rather than the mesh:

#exec ANIM SEQUENCE ANIM=SkeletalAnimation1 SEQ=All STARTFRAME=0 NUMFRAMES=25 RATE=0.2 GROUP=Default

In any case, a specific DIGEST command needs to be issued, at which point all sequences (implicit and declared) are compressed into the internal key track format:

#exec ANIM DIGEST ANim=SkAnimTest VERBOSE

Specify VERBOSE to see more information in UCC.log after the rebuild.

Notification callbacks need to be placed after the #exec ANIM DIGEST, and have a syntax similar to the old notify commands:

#exec ANIM NOTIFY ANIM=SkeletalAnimation1 SEQ=All TIME=0.1 FUNCTION=LandThump

A UAnimation object is linked to a certain skeletal mesh at runtime using LinkSkelAnim:

function PostBeginPlay()
{
    LinkSkelAnim(Animation'SkeletalAnimation1' );
    LoopAnim('All',1.0,0.0);
}

Or (more useful for backward compatibility) it can be linked at compile time using:

#exec MESH DEFAULTANIM MESH=MeshSk ANIM=SkAnimTest

LOD works the same as regular LOD in Unreal Tournament. See LODTechnologyNotes.htm.

When your skeletal animation makes your character cover an area far outside its reference pose or root position, you have the option to override the bounding box extents that the engine uses to determine visibility.

#exec MESH BOUNDINGBOX MESH=MeshSk XMIN=-64.0 YMIN=-64.0 ZMIN=-64.0 XMAX=64.0 YMAX=64.0 ZMAX=64.0

There is a tradeoff: make the bounding box too big, and the mesh will be drawn in situations where it is occluded by architecture; make it too small, and meshes may flicker in and out of view.

Materials

The names of the multi/sub materials indicate which rendering modes will be activated for the polygon flags. The following strings fragments, with the familiar Unreal polygon effects, can be anywhere in the material name and can be combined (if the combination makes sense to the engine.)

Recommended: when using multiple textures, always name them skin00, skin01, etc, which will force the 'multiskin' indices to point at the textures in a predictable order.

  • skinXX - give your materials numbered skin names to ensure they are linked in the right order, whenever you have multiple skins for a single mesh.
  • twosided - twosided (flags, fins)
  • weapon (obsolete) See Weapon Bone.
  • invisible (obsolete)
  • modul - modulated
  • mask - masked
  • envir - environment mapped
  • mirro - environment mapped
  • nosmo - 'nosmooth', non-bilinear filtered
  • unlit - unlit
  • trans - translucent

You still have to create your own 8-bit .pcx or .bmp versions of texture files and manually link them up in the appropriate .uc script files, but you can look at the X_ModelInfo.log output to see exactly which bitmap files go with what material number for your model.

Log Files

The exporter does not output explicit '.uc' template script files, instead it writes X_AnimInfo.log and X_ModelInfo.log which contain a detailed summary of the exported data, and have all the information about frames and material/bitmaps you need when writing the script #exec commands that link in the data.

The log files are always dumped in the same folder along with the .PSA/.PSK files.

Weapon Bone

Instead of assigning a polygon in Max, you now assign any bone as a weapon-carrier using MESH WeaponAttach, with the name of the bone as visible in Max:

#exec MESH WEAPONATTACH MESH=MeshSk BONE="Right hand"

The actual position can be fixed up. (so you're not forced to link an extra bone to the skeleton to achieve the right position)

#exec MESH WEAPONPOSITION MESH=MeshSk YAW=50 PITCH=0 ROLL=10 X=0.0 Y=0.0 Z=0.0

This attachment point is then fully backward compatible with Unreal Tournament's weapon polygon.

Important notes

  • When setting up a skeleton, regardless of whether you're using Max or Maya, make sure each and ever bone/joint has a unique name. Take special care to do this after you've constructed a skeleton using mirroring. The code that resolves the hierarchy and linkups, both in the exporter and in the engine, assumes that unique names are used.
  • The visibility bounding-box extents are determined from the reference pose, not the entire range of animations as was the case for vertex animations. To compensate for the possibility that animations extend far beyond the bounds of the reference pose, the code currently uses the reference pose limits and scales those out once more, to estimate a safe size as used for visibility determination. If meshes still flicker, it may be because the animations that were exported stray too far from their reference pose / origin position, and move beyond the boundaries where the engine expects it to be. You can override the bounding box extents with the "BOUNDINGBOX" #exec command.
  • Skins: the best way to currently guarantee that the order of skins isn't messed up is to strictly follow "skin00, skin01.." naming conventions for your multi/sub materials in Max.
  • Root pose issues: to prevent anomalous vertex assignments slipping in when exporting the .PSK file, it is recommended to export it from either an explicit root pose (as can be activated with bipeds in Character Studio) or in any case, make sure frame 0 is reachable as part of the active time slider so the exporter does not get confused with the skin's versus the bones' reference poses.
  • When the mesh shows messed up in the engine, it's usually a matter of the .PSK not matching the .PSA. This can happen even if they're exported from the same Max file in some cases. Reference skin PSK files are saved from the first available frame; when the first frame is hidden, and the animation bar is set to show only a subset of the frames, the exporter may get confused and associate the bone reference pose with the wrong skin reference pose. It's easiest to keep a special original .max file which contains this 'reference pose', the right skin/material linkup, and no animation, so you can always rely on that as the source for the .PSK file, without having to mess with the start-time of animations.
  • Orientation/height problems: due to the different 3D axis assignments in Unreal, Max and Maya, if no adjustments are applied, Max characters come out turned 90' sideways, and Maya characters turned on their backs. Also, in most cases it is convenient to have feet placed on the zero plane when editing/animation characters, while the engine may, depending on game code, rely on some actors (like player models) to be centered around zero instead.
    Orientation and height can be adjusted in script (at rebuild time, rather than engine-runtime)
    right after the .PSK import statement, using the MESH ORIGIN commands:

    Typical maya orientation adjustment:
    #exec MESH ORIGIN MESH=PistonMesh X=0 Y=0 Z=-32 YAW=64 PITCH=00 ROLL=64
    Max player height adjustment:
    #exec MESH ORIGIN MESH=WarBossMesh X=0 Y=0 Z=90 YAW=0 PITCH=0 ROLL=0

[end of document | back to top]

Copyright Epic Games 2000

Erik de Neve | erik@epicgames.com


Unreal Creature Care and Feeding Guide

Steven Polge
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Level designers, programmers.
Last Updated: 01/25/02

AI Attributes

Typically, you will use the default values for the parameters below, with the following exceptions:

  • Tag, Orders, Ordertag,TeamTag, bTeamLeader, AlarmTag and sometimes Aggressiveness. AttitudeToPlayer, and Combatstyle.

Actor attributes menu:

  • OddsOfAppearing Likelihood that creature (or other actor) will appear in relevant game modes. Range is 0.0=Never to 1.0=Always (default is 1.0).

Display attributes menu:

  • DrawScale: If the drawscale of a creature is changed from its default value, its collision box (collisionheight and collisionradius) and health will be scaled by the new value at the start of gameplay.

Movement attributes menu:

  • JumpZ: How far a pawn can jump. If you don’t want a pawn to jump that can normally jump (for example, you want to keep a specific Skaarj up on a ledge), set its JumpZ to -1.

AI attributes menu:

  • bHasRangedAttack: specifies whether creature can attack from beyond melee range.
  • bMovingRangedAttack: specifies whether creature can use his ranged attack while moving (assuming creature supports this mode).
  • bCanStrafe: Specifies whether creature can strafe.
  • bFixedStart: If true, creature always starts from where it was placed. If false, then may start from alternate position depending on its orders (see below).
  • bQuiet: If true, makes less noise when wandering around
  • bTeamLeader: Leader of his team (as defined by the TeamTag). There should be only one per team.
  • bIgnoreFriends: Default false. If true, creature doesn’t react to friend's noises.
  • bDelayedPatrol: If true, and creature’s orders are Patroling, then the creature will begin his patrol only when it is triggered. However, it will break off this patrol and react
  • to the player if it sees him. To force the creature to continue to his destination, you can also specify the patrol destination in the creature’s alarmtag.
  • bHateWhenTriggered: Creature will change its attitude to hate the player when triggered by the player.
  • TeamTag: Creature team to which this creature belongs. As long as the team leader is alive, creatures on the same team will coordinate with each other.. If the species can speak, then creatures on the team will talk to each other.
  • Skill: Added skill of this creature. Default is 0. For example, if Skill = 1, then the creature will act like a difficulty 2 creature when the difficulty setting = 1.
  • SightRadius: Maximum sight distance. Creature’s likelihood of seeing other pawns depends on how far away the other pawn is relative to the creature’s sight radius. the other pawn’s visibility, and (soon) how well lit the other pawn is.
  • PeripheralVision: The cosine of the maximum angle of peripheral vision. A creature which can see 90 degrees to each side (180 degrees total) would have PeripheralVision = ?.
  • HearingThreshold: Minimum scaled noise loudness which can be heard. While the exact hearing range depends on the creature’s alertness, a good rule of thumb is that creatures can hear a typical loud noise if there is a line of sight to the noise location, and HearingThreshold < 200 / (distance to the noise in Unreal units). For example, a creature with HearingThreshold = 0.4 could typically hear noises if they were no more than 500 units away. A hearing threshold of 0.2 translates to a max hearing distance of 1000 units. Creatures can never hear noises which are more than 2800 units away.
  • Orders: See Orders section below.
  • OrderTag: See Orders section below.
  • TimeBetweenAttacks: Time in seconds between ranged attack barrages (which may include multiple shots).
  • MeleeRange: Maximum distance from target (not including collision radius of this creature or its target) to launch a melee attack.
  • Aggressiveness: Typically in the range 0.0 to 1.0. Primarily affects attitude changes (more aggressive creatures will continue to fight, even against a stronger player, less aggressive creatures will be more quick to flee). May also have an effect on tactical combat decisions. Note that creatures will only run away if they have a home base (except for Nali and cow)
  • Visibility: How visible is this pawn to other creatures (note - does not affect rendering!) 0 = invisible, 128 = normal, 255 = highly visible.
  • AttitudeToPlayer: Initial attitude to player (may change depending on player’s actions, and creature's aggressiveness.
    • ATTITUDE_Fear - creature will try to run away
    • ATTITUDE_Hate - creature will attack player
    • ATTITUDE_Frenzy - Indiscriminate, berserk attack (no fear, lower accuracy)
    • ATTITUDE_Threaten - Creature will assume a threatening posture
    • ATTITUDE_Ignore - Creature will ignore player
    • ATTITUDE_Friendly - Creature will fight player’s enemies
    • ATTITUDE_Follow - Creature will follow player (not yet implemented).
  • Intelligence: Creature’s intelligence
    • BRAINS_None - amoeba like - only reacts to immediate stimulus
    • BRAINS_Reptile
    • BRAINS_Mammal
    • BRAINS_Human
  • ReFireRate: Likelihood of firing again immediately after a ranged attack (values from 0 to 1 with higher values indicating a higher probability).
  • CombatStyle: Tactical decision making during combat. Value between 0.0 and 1.0 Higher means the creature is more likely to charge, try to melee, etc.
  • AlarmTag: If AlarmTag is set, when the creature sees the player, it will (at all costs) first go to the actor with the same Tag as its AlarmTag. Friendly creatures will wait for the player as they move towards this actor. This can be used either to have friendly creatures lead the player to some area or object, or for unfriendly creatures to try to trigger events or set up initial attack formations. For example, you could have three Kraal in a room. Two attack you, while the other runs for a button which will lock the door behind you and sound an alarm. Alternatively, you could have them spread out in formation, seeking cover or advantageous positions when they see you. AlarmPoints (see below) are designed to provide extensive scripting control when used with the AlarmTag.
  • SharedAlarmTag: For each group of creatures who have the same string in this field, one of them will choose it to be his alarmtag (overriding any existing alarmtag). You can use this to provide some randomness in which creature performs some important action.
  • DropWhenKilled: Creature will drop one of these when it is killed.
  • FirstHatePlayerEvent: Creature will trigger this event the first time he decides to attack the player.

Orders

The following initial orders can be given to all creatures. After killing an enemy, they will attempt to continue to execute these orders. Some orders (patroling, guarding) are associated with other actors in the level. For these, you should set the creature’s OrderTag to the tag of the associated actor.

Waiting

The default orders for all creatures. Creature will wait in place, playing various waiting animations, until it receives some external stimulus (sight or sound).

Patroling

Patroling creatures will patrol along a set of Patrolpoints (a subclass of NavigationPoint) specified by the level designers. The creature’s OrderTag should contain the tag of the first Patrolpoint in its patrol. When a creature reaches a Patrolpoint, it will pause for the PauseTime specified in the patrol point, facing in the direction the Patrolpoint is oriented. While pausing, it will play waiting/patrolstop animations. If a PatrolAnim is specified, the creature will play that specific animation the number of times specified by NumAnims. Each time it plays the animation, it will also play the PatrolSound if one is specified. Note that the amount of time creatures playing a PatrolAnim pause depends on how long it takes to play the animation NumAnims times, and not the pause time. However, the PauseTime must still be set to a positive number. It will then continue to the Patrolpoint specified in the current Patrolpoint’s NextPatrol. If a creature cannot reach the next patrol point, it will wait at its current position. If bFixedStart is false, the creature will start at some random point along his patrol route (not yet implemented).

Guarding

Guarding creatures will guard the actor whose tag equals their OrderTag. They will remain near, and try to return the guarded actor after combat. If their initial attitude is ATTITUDE_Threatening, they will threaten the player, and try to remain between the player and the guarded object. If the player touches the object they will attack.

Ambushing

The creature is waiting, but more alert than in the waiting state (and possibly playing different animations). If bFixedStart is false and there are Ambushpoints (a subclass of Navigationpoint) with the same tag as the creature, the creature may randomly pick one of these as its starting point. The orientation of the Ambushpoint determines the orientation of a creature using it. Ambushpoints may also be used by creatures that decide to ambush rather than pursue a player.

Swarm AI Pawns

Horseflies, biterfish, and blobs all use variations of swarm AI. Do not place individual Horseflies and biterfish in your map. Rather, place horseflySwarms and biterfishSchools, and specify in their properties how many individual creatures they should contain. For blobs, add a parentBlob and a number of bloblets, and give them all the same tag.

PathNode placement

You can place pathnodes manually, or you can use PATHS BUILD LOWOPT from the console to get a first pass placement done automatically. In any case, you must do a PATHS DEFINE from the console to create the connections between pathnodes.

To use the navigation system, a creature must first choose the best nearby node to "get on" the network. For performance reasons, creatures limit their search for path nodes to those within an 800 unit radius (see FSortedPathList::FindVisiblePaths in UnRoute.cpp). This is because the test to determine if a creature can reach a path is very expensive. However, once creatures are "on the network", travelling from pathnode to pathnode, they use the reachspec tables in each pathnode to determine reachable nodes. There is no distance limit for reachspecs, so paths may be defined between two pathnodes which are any arbitrary distance apart. For performance reasons, paths between distant pathnodes which have a suitable alternate
path using intermediate path nodes (with a low added cost) are culled from the path network.

I recommend that paths should be less than 700 units apart, so that creatures don't ever start off going in the wrong direction to get on the network. In addition, paths on stairs and ramps should be closer together (<350 apart) Given that, you should use the minimum number of paths needed to cover the area for which you want intelligent navigation. Note that all navigation points are equally used as paths, so there is no need to place pathnodes redundantly near patrolpoints, etc..

Paths should in general be placed at intersections, making sure that they have the maximum visibility in all potential directions. Paths need a line of sight to each other, clear to the width of the maximum width (2 * collisionradius) of creatures which will use this path. You should also place paths on ledges, with a line of sight to paths below, so that creatures can intelligently navigate jumping off ledgest. Vertical line of sight has no extent requirement.

In UnrealEd, look at the Properties menu in the map view window. There is an option to show the path connections. These are best looked at using the overhead view. Note that a connection between two Navigation points indicates that at least some creatures can use this path. However larger creatures, or creatures which do not support certain movement modes (e.g. the bCanJump, bCanSwim, etc. attributes of pawns) may not be able to use these paths.

Thing Factories and Creature Factories

Creature and thing factories may be triggered by a trigger whose event equals the creature factory’s tag, or will trigger themselves if a player touches it. Since zone changes can cause an event, you could for example cause a creature factory to start producing razorfish as soon as a player enters the water. The first creature spawns instantly. Creature and thing factories use Spawnpoints ( a type of navigation point) as the locations to create actors. Up to 16 spawnpoints can be associated to a given factory. Spawnpoints and creature factories are associated by giving them the same tag. If a Spawnpoint has a tag in its event field, that event will occur when a creature is spawned from that spawnpoint. By default, creature factories are covert, which means they will only spawn actors at a spawnpoint no player can see. A creature from a factory has its event set to the factory’s tag (so its death will trigger the factory). Thing and creature factory properties are:

  • prototype: The class of actors produced by this factory.
  • maxitems: The maximum number of active actors from this factory at any time. If it is a creature factory, new creatures will only produced either initially, or when a creature dies, to get back up to maxitems until the factory capacity is reached.
  • Capacity: The maximum number of actors this factory can ever produce (-1 = no limit). After reaching this limit, the factory shuts down.
  • AddedCoopCapacity: Extra items to produce if the game type is CoopGame.
  • Interval: The average time interval between spawns.
  • timeDistribution: The distribution of the interval between spawns.
    • DIST_Constant - constant interval (always equal to Interval).
    • DIST_Uniform - uniform interval (random time between 0 and 2 x interval)
    • DIST_Gaussian - Gaussian distribution, with mean = interval
  • bOnlyPlayerTriggered: Only a player can trigger this factory (true by default).
  • bCovert:; Only do hidden spawns (true by default for Creature factories, false by default for thing factories).
  • bStoppable: Stops producing when untouched.
  • Orders: (Creature factory only) Creatures from this factory will have these orders
  • OrderTag: and ordertag. By default they will attack the instigator of the factory.
  • ItemTag: Tag given to items produced by this factory.
  • AlarmTag: (Creature factory only) AlarmTag given to creatures produced by this factory.

Navigation Points

All navigation points have a bPlayerOnly attribute. If set to true, it means that only Players (bots) will use this path for navigation. Its not perfect, but if you put two in a row along a hallway with turns, it will probably keep the creatures from going through that hall. Exceptions are if the creature is close behind a player and in hot pursuit, or if he is already very close to the path when he tries to use navigation.

Homebase

Homebase of creatures whose tag is the same as the Homebase actor. Creatures who fear the player will flee to their homebase if they have one. There, they will turn and fight. When a creature reaches its homebase, it will face in the direction specified by the homebase’s orientation. Also, it will check for nearby ambushpoints whose tag = the creature’s tag, and if any are found will go to them.

Ambushpoint

See Ambushing orders.

InventorySpot

Automatically inserted during PATHS DEFINE to identify location of inventory (for bots.

Teleporters

PlayerStart

SpawnPoint

See Thing and Creature factories.

PatrolPoints

See Patroling orders.

LiftCenter

Place this Navigation Point at the spot on a lift you want the creature to stand while using the lift. Its LiftTag should be set to the tag of the lift it is on.

LiftExit

LiftExits should be place at the spots you want creatures to wait before getting on a lift. Their LiftTag should be set to the tag of the lift they are associated with.

AlarmPoints

Alarmpoints are designed to be used in conjunction with the alarmtag to cause creatures to perform complex actions upon seeing a player. If the Alarmpoint’s event is set, it will trigger all creatures with that tag when the alarm creature reaches the Alarmpoint. The attributes are:

  • NextAlarm: The next alarmpoint to go to after this one. If none, the creature will revert to normal AI after completing the actions specified by this point.
  • PauseTime: How long to pause at this alarmpoint.
  • DuckTime: How long to pause after playing the AlarmAnim (only used if an AlarmAnim is specified). Its called ducktime, because a typical use would be to have the creature duck, wait for ducktime, and then stand up and shoot (if bAttackWhilePaused is true). If you want to the creature to track the player while ducking, be sure to set bAttackWhilePaused.
  • AlarmAnim: If specified, the creature will play this animation upon reaching the alarmpoint, as well as the AlarmSound if specified.
  • bStrafeTo: If true, and the creature can strafe, then the creature will strafe to this AlarmPoint, facing the enemy player. If the creature has a moving attack, it will fire while strafing if it has a clear shot.
  • bAttackWhilePaused: If true, the creature will shoot at the player while paused (unless he has a ShootTarget). If the player is not visible, the creature will fire at where he last saw the player.
  • bNoFail: If true, the creature will never give up trying to get to this Alarmpoint (just as it never gives up trying to get to other alarmtag actors). If false, and the creature gets knocked off its path, it may give up if it can no longer easily get to the alarmpoint.
  • bStopIfNoEnemy: If true, and the enemy is not visible, creature will stop at this Alarmpoint until it sees the enemy again. Otherwise, it will continue progessing through the Alarm actions.
  • bKillMe: Any creatures that are triggered by this alarmpoint (their tag = the alarmpoint’s event) will hate and kill the triggering creature, even if they wouldn’t normally.
  • bDestroyAlarmTriggerer When a creature reaches this alarmpoint (and it is the creature’s alarmtag destination), the creature is immediately destroyed.
  • ShootTarget: If bAttackWhilePaused is true and ShootTarget has the tag of some actor, the creature will fire at that actor rather than the player.
  • AlarmSound: If an AlarmAnim is specified, the AlarmSound will be played in conjunction with the AlarmAnim.

Physics Notes

Creatures may be able to walk over any opening up to 3X their CollisionRadius. If you want something to definitely fall in, or not be able to cross without jumping, make it bigger than this. Also, make sure that most hallways, and particularly intersections and corners are at least (4 x CollisionRadius + 10) of the largest creature you want to navigate it (so that two creatures won’t get hung up with each other. Ideally, hallways should be at least 6x the CollisionRadius of the largest creature which may navigate it. Also WarpZones should be at least 70 units deep ideally to allow the AI to handle them properly.

Triggering creatures

Creatures that have not engaged an enemy can be triggered by a trigger whose event equals the creature’s tag. Creatures that are triggered will make whatever instigated the trigger their enemy. You can use this to have creatures ignore the player until a certain event happens, such as crossing some threshold (using ATTITUDE_Ignore) - if bHateWhenTriggered is true, the creature will change its attitude to hate the instigator. Creatures will also trigger their event when they die. You can use triggers in conjunction with bDelayedPatrol to cause a creature to start a scripted set of actions when triggered by the player (without noticing the player).

Triggers

Two new trigger types have been added. TT_PawnProximity will allow any pawn, not just players to use the trigger. TT_ClassProximity will only allow actors of the class ClassProximityType to use the trigger. For example, you might make a certain switch only operable by a Nali. Also, triggers with type TT_Shoot now also have an optional DamageThreshold value. This is the minimum damage required for triggering (instantaneous, not cumulative). The optional attribute ReTriggerDelay specifies the minimum time before a trigger can be triggered again.

RepeatTriggerTime, if set to a value greater than zero, causes the trigger to send out its event at an interval of RepeatTriggerTime seconds while the triggering actor remains within the trigger’s radius.

EarthQuake

The EarthQuake keypoint can be triggered to shake the player’s view for a specified duration, as well as possibly tossing players around. It has no effect on other actors. To simultaneously toss around other actors, use the ThrowStuff keypoint. Earthquake attributes are:

  • magnitude: Specifies the amount to roll the player’s view, and the amount to throw him if bThrowPlayer is true. A magnitude of 2000 is a pretty strong quake.
  • duration: Time in seconds quake lasts.
  • radius: Radius for which players are affected. A player who goes beyond the radius will continue to have his view shaken for the duration of the quake, but he will no longer get thrown around.
  • bThrowPlayer: If true, players are thrown around during the quake.

ThrowStuff

The ThrowStuff keypoint can be used to cause actors whose tag matches the ThrowStuff keypoint’s event to be tossed using the vector specified in throwVect. If Numthrows is larger than 1, the actors will be thrown again after the specified interval. If bRandomize is true, the throwVect will be randomly altered for every toss. Having Numthrows > 1 and bRandomize can be useful for making stuff get tossed around during an earthquake. Other potential uses for a ThrowStuff keypoint include launching a creature in a specified direction when triggered by the player, or turning the physics on of actors when a brush they are on tips and you want them to slide/fall off (in this case, use a ThrowVect of (0,0,0), and they will just be set to falling).

MakeNaliFriendly

When triggered, this keypoint makes all Nali in the level friendly. This is useful for cases when the player may have scared the nali previously, or to set up situations where the Nali will reward the player after he does something (such as killing a skaarj which was threatening the Nali).

Jumper

When triggered, this trigger makes the triggering creature jump in the direction it is pointing. It can be limited to trigger once only, or to only affect a certain class of creatures. The Jumper trigger has a JumpZ variable which specifies how high the triggered creature should jump (giving you control over where it lands).

FearSpot

This trigger causes creatures to avoid an area (not perfectly).If you use this, make sure there are also no paths going through the area you want them to avoid. The FearSpot keypoint has a bInitiallyActive attribute, which can be turned on and off by triggering it.

Movers

Two new booleans have been added to Movers. bUseTriggered indicates that the brush is activated by a player doing a use (exec grab) on it. BDamageTriggered indicates that damage to the brush will trigger it. The optional attribute DamageThreshold specifies the minimum (instantaneous, not cumulative) damage needed to trigger a bDamageTriggered brush.

Mover bump types are now supported, specifying which types of actors can trigger a mover by bumping it (for movers which are activated by bumping).

By default, all the movers with the same tag will return or stop if one returns or stops because of encroachment. To prevent all the movers with the same tag from acting this way, you can divide them into sub-groups using the ReturnGroup attribute.

Special Creature Features

Mercenary

The mercenary has several special sets of idle animations accessible through the following attributes - bButtonPusher, bTalker, and bSquatter. If one of these attributes is set true, then these animations will play whenever the mercenary is stopped (waiting, or stopped on patrol, etc.). Note that for bTalker and bSquatter, the mercenary should be talking to teammates (so that the conversation will be synchronized).

bHasInvulnerableShield, bCanFireWhileInvulnerable, and invulnerableCharge are parameters which can be used to adjust the Mercenary’s invulnerability capabilities.

Skaarj

The Skaarj has a special set of animations accessible through the attribute bButtonPusher, which work in an analogous fashion to the mercenary bButtonPusher animations. Also, bFakeDeath tells the skaarj to remain laying down until a little after he sees the player. Note that skaarj using bFakeDeath should be placed slightly above the floor, so they don’t adjust out of the floor on first seeing the player (thereby giving away the fact that they are not really a carcass).

Krall

The Krall has a special set of animations accessible through the attribute bDicePlayer. Krall using these animations should be teamed with several other Krall and closely arranged in a circle. The bSleeping attribute will make a Krall play a sleeping animation and be very un-alert while waiting.

Nali

A Nali with orders "Guarding" will play his praying animations. A Nali with orders "Ambushing" will play his meditating animation.

The bNeverbow attribute should only be used with Nali who have a homebase (and only in well tested situations). When enabled, the Nali will not stop and bow while retreating.

Birds

Although birds are flockpawns, they are added individually. They have several different selectable behaviours. By default, they will fly around randomly in an area whose size is

determined by their CircleRadius attribute. Note that this area should be relatively free of obstructions, as birds are not smart. If bCircle is set, they will soar around a circle with radius CircleRadius. If GoalTag is set, they will not move until triggered, and then quickly fly to their GoalActor. Birds are now unlit by default. If you want a bird to show off cool light/shadows, then set its bUnlit property to false. Birds that you don’t see no longer cost anything. However, be sure not to use birds in big open areas where they can be seen from far away, as the full cost of rendering their mesh still exists, even if they are smaller than a pixel.

Cow and Rabbit

The bStayClose attribute (on by default) specifies whether the creature will wander around within its WanderRadius, rather than wandering randomly anywhere.

Pupae

Pupae can be placed and rotated onto any wall or ceiling initially. When they see the player, they will drop off the wall/ceiling and go at the player.

Brute

The bTurret attribute when true will make the Brute stay in place and just fire at the player.

Warlord

The Mutilating orders are for hub one. The Warlord has a new attribute, bTeleportWhenHurt, which causes him to teleport away rather than dying.

BiterFishSchool

The bNonAggressive attribute when true will make the fish ignore the player. BiterFishSchools have a fishcolor attribute. 0 to 6 makes all the fish in the school the same color, while a value larger than 6 gives them a random mix of colors.

Carcasses

You can add permanent creature and player carcasses (they are a subclass of decoration). If a creature has multiple death animations, you can select the death pose by changing AnimSequence in the Display properties.

Carcass management note: Carcasses are destroyed more quickly in zones that already have reached their limit of carcasses. In less cluttered zones, carcasses will never disappear or change forms before your eyes. The MaxCarcasses attribute of zones sets the limit for "uncluttered" carcasses in a zone. The default is now 3, which should be optimal for most situations.

Zones

The ZoneTag is used to tag a zone which is to be triggered by a ZoneTrigger. WarpZones can be triggered to sequence through an array of destinations specified in their properties. Other zones will toggle bPainZone when triggered. The ZoneFog and ZoneFlash properties in ZoneLight allow you to change the player’s display color/fogging for a given zone.

The ZoneTerminalVelocity attribute changes the maximum falling speed of players in the zone.

There are now also EntrySound, EntryActor, and ExitSound attributes for zones. Zones with bWaterZone set will play these as pawns enter/leave the zone. These are modified for special water zones, such as lava or slime.

When a player enters a TeleporterZone, he is teleported by the associated teleporter (specified by the TeleporterZone’s TeleporterTag).

Screen Flashes

There are two components used to create screen flashes. ViewFog is used to color the screen. It is a vector whose components are RGB values between 0 and 1. As ViewFog increases the brightness of the screen, you need to use ViewFlash to keep it from over-brightening.

ViewFlash is a vector whose components should be between 0 and –1 (for example (-0.5, -0.5, -0.5). It reduces the brightness of the screen. Typically, all the components will have the same value, which should have a magnitude about the same as the average magnitude of the ViewFog components to keep the screen from changing brightness.

AI Difficulty Differences

Write this.

Scripted Execs and Cheats

Game Commands

  • FeignDeath pretend to be dead
  • Grab Pick up a decoration or "use" a mover
  • Say "xxx" Send message "xxx" to all players
  • RestartLevel
  • ThrowWeapon Toss out your current weapon.
  • Kick "name" Kick player named "name" off of server (only from bAdmin)
  • Pause
  • SwitchWeapon n Switch to weapon in weapon group n
  • Fire
  • AltFire
  • Jump
  • Suicide
  • AlwaysMouseLook b If b=1, always mouse look (and turn off SnapToLevel and
  • LookUpStairs. If b=0 turn off AlwaysMouseLook.
  • SnapView b If b=1, snap view back to horizontal when MouseLook is unpressed (and turn off AlwaysMouseLook). b=0 turns it off.
  • StairLook b If b=1, turn on automatic view orientation up and down stairs/slopes.
  • SetDodgeClickTime f Modify the dodgeclicktime (time between button presses for dodge move. F must be less than 0.3. A negative value disables the dodge move.
  • SetName "xxx" Change your name to "xxx".
  • SetTeam "xxx" Change your team to "xxx".
  • PlayersOnly Only players allowed in the level.
  • ViewPlayer "xxx" View the game from the point of view of the player named "xxx".
  • The view is only changed if you are allowed to see through this player’s eyes (e.g. a teammate in team play or coop mode).
  • SetAutoAim f Adjust autoaim. Setting it to 1.0 disables it.
  • SetHand xxx Set weapon hand to xxx= left, right, or center.
  • Taunt xxx Play the taunt animation xxx (wave, victory1, taunt1)
  • NeverSwitchOnPickup b Default is 0. If set to 1, then you never automatically switch to a picked up weapon.
  • PrevWeapon Switches to the next lower priority weapon.
  • NextWeapon Switches to the next higher priority weapon.
  • InvertMouse b Default is 0. If set to 1, then your mouselook is inverted.
  • ShowScores Toggles the display of the scoreboard in multiplayer games.
  • ShowMenu Cause the menu to be displayed.
  • SetSensitivity f Changes the mouse sensitivity scaling to f (a float).
  • SetBob f Changes the bob value to f (default is 0.016).
  • AddBots n Adds n bots to the level (game must be a DeathMatchGame or Subclass).

Cheats

  • ViewClass xxx View the game from the point of view of a member of class "xxx". Successive executions of this function will iterate through the class. For example, ViewClass class’SkaarjWarrior’ will show you the game from the point of view of a Skaarj in the level, if there is one.
  • KillAll xxx Kills all actors of class xxx (including subclasses)
  • Amphibious Makes you amphibious (no limit to underwater time).
  • Fly
  • Walk
  • Ghost
  • ListInv Print a list of your inventory items to the log.
  • AllAmmo Gives you 999 ammo for all the weapons you have.
  • Invisible b b=1 makes you invisible. b=0 makes you visible.
  • TempStatus b b=1 turns the temporary status bar ( at the top of your screen) on. b= 0 turns it off.
  • God Toggles god mode.
  • BehindView b
  • SloMo f Changes the rate of time in the game. 1.0 is normal speed. 2.0 is twice normal speed. 0.2 is one fifth normal speed…
  • Players Prints a list of players and their current score.
  • JumpZ Changes your jumping height (260 is default).
  • KillPawns Removes all pawns from the game.
  • CheatAdd class’xxx’ Adds an actor of class ‘xxx’ right in front of you. This can be anything (a weapon, ammo, a creature, etc.), as long as an actor of that class exists or is referenced in your level.
  • RememberSpot Remember your current location (see ShowPath below).
  • ShowPath Show recommended path back to location remembered by
  • RememberSpot. Displays a beacon. When you touch that beacon, it shows the next one.
  • SetDesiredFOV f Sets your field of view to f (a value between 1 and 179).

End


Unreal Tournament AI and Gameplay for Level Designers

Steven Polge
Epic MegaGames, Inc.
http://www.epicgames.com/

Audience: Level designers, programmers.
Last Updated: 11/30/99

Porting Unreal I maps to Unreal Tournament

Unreal I content is automatically replaced by Unreal Tournament content if you run an Unreal I DM map with one of the Unreal Tournament gametypes. However, we recommend that you manually replace the Unreal I inventory items in your level with their UT equivalents and release an updated version of the map. Otherwise, both the Unreal I and UT versions will be loaded on the content, which will cause swapping on clients with low amounts of memory.

The Navigation Network

Creating the Navigation Network

Unreal Tournament bots use a system of waypoints to navigate the level. Using waypoints allows UT to minimize the CPU cycles used by the AI, and gives level designers maximum control over how the AI navigates their levels.

These waypoints are defined by placing actors which are subclassed from NavigationPoint in the level. This includes actors such as PlayerStarts and Teleporters which designers will place to make their level playable. Certain NavigationPoints, such as InventorySpots and WarpZoneMarkers are automatically placed when the designer "defines" the paths (described below). Other NavigationPoints are intended for Unreal I style single player situations and are not used at all in UT. These include AlarmPoints, ButtonMarkers, PatrolPoints, QueenDests, SpawnPoints, Transporters, and TriggerMarkers.

Once the level geometry is complete, the level designer should fully map the level into the navigation network using PathNodes. Place PathNodes at intersections and turns so that there is as much clearance as possible from corners (at least 50 world units if possible). Paths need a line of sight to each other, clear to the width of the maximum width (2 * collisionradius) of creatures which will use this path. PathNodes should not be placed more than 700 units apart. Since PlayerStarts and Inventory will be placed on the navigation network, the designer can (and should) not place PathNodes where these other NavigationPoints can substitute. On stairs and ramps, the PathNodes should only be 350 units apart. The objective should be to use a minimum number of PathNodes to completely cover a level.

Version 402 of Unreal Tournament has an automatic PathNode generator which will do part of the work of placing paths automatically. It will attempt to cover the level with paths, but will not place special NavigationPoints such as playerstarts, liftcenters, etc.. To use the automatic PathNode generator, open your level in UnrealEd. Select the Window menu, and from it the log. At the prompt type 'Paths Build' (no quotes). This will take 5 to 10 minutes for a typical level.

To navigate around the level, bots will first find the nearest reachable NavigationPoint, and move to it. They will then move toward their destination, going from NavigationPoint to NavigationPoint. It is important that some NavigationPoint is reachable (there are no obstructions in the way) from any location a bot may reasonably get to in the level. If a bot can't find a valid path, either because it can't find a way to get on the network, or there is no valid way to get from the network to its destination, or the path on the network is broken, then the bot will wander (walking) around its current area.

The final step in setting up the navigation network is performing a PATHS DEFINE. This can be done by typing PATHS DEFINE into the UnrealEd console, or pressing the "Paths Define" button in the lighting section of the rebuild window. The designer can examine the network generated in any of the UnrealEd world view windows by selecting "Show Paths" from that window's "View" menu. NavigationPoints which are successfully connected will have either blue or red lines between them. Bots will use either blue or red paths, but blue paths are preferable - they indicate a cleaner, more obstruction free path. Each time geometry is changed or NavigationPoints are added or moved (including inventory, since paths are generated from inventory items), a PATHS DEFINE should be performed.

There are several common problems that result from assumptions and approximations made by the AI to minimize CPU overhead. Make sure that all NavigationPoints are separated by at least 50 world units. If two pathnodes are too close together, a bot may get stuck on them. The editor log window will display warnings during a PATHS DEFINE if paths are too close together. This problem commonly occurs with InventorySpots, which are automatically placed near all inventory items. Don't place PathNodes too near to inventory.

In some situations, bots may get stuck on the edge of a ledge where it runs into a wall. This occurs because of a threshold problem. Bots won't jump off ledges until the angle of their destination is greater than 45 degrees from the ledge direction. If they run into a wall right around this threshold, they may get confused. The solution is to adjust the NavigationPoint they were trying to reach, or add an intermediate PathNode.

Bots will have problems if the NavigationPoints are too high off the ground. Make sure that the NavigationPoint is no more than 1.5x the bot's collisionheight off the ground. This will normally be the case automatically, but in a few situations (such as very steep ramps), the level designer may need to manually adjust the Z position of the NavigationPoint.

PathNodes for the bots to use while swimming must be in the water. Placing paths above the water's surface will result in bots bobbing at that spot, attempting unsuccessfully to levitate to the PathNode's location.

WarpZones should be at least 70 units deep to allow the AI to handle them properly.

Adding Support for Lifts

There are two special NavigationPoint classes used to help bots understand how to use lifts, LiftCenters and LiftExits. Give the lift a unique tag. Place a LiftCenter on the lift, and set its LiftTag attribute to be the tag of the lift. At each exit from the lift, far enough away so that bots standing at that spot won't interfere with the lift, add a LiftExit. Each LiftExit should have its LiftTag set to the tag of the lift.

The default state for movers is BumpOpenTimed. Do not use this state for lifts! Bots misinterpret movers that are BumpOpenTimed as being doors. Instead, use the StandOpenTimed state for most lifts. Bots will also understand triggered lifts (TriggerOpenTimed, TriggerToggle, etc.). In many cases, they will use triggered lifts without any further help. However, for certain complex situations, such as when a delayed dispatcher is used to control the lift, bots may need a hint. In these cases, set the LiftCenter's LiftTrigger attribute to the tag of the trigger the bot should use to control this lift.

There are two other configurable LiftCenter attributes of interest. These should be modified only if absolutely necessary. MaxZDiffAdd, which defaults to 0, specifies an additional allowable difference in height between the bot and the LiftCenter for the bot to consider that LiftCenter reachable. This is useful if the bot must stand below the lift (down stairs or a ramp) while waiting for it. MaxDist2D is the maximum distance between the bot and the LiftCenter. It defaults to 400 world units.

NavigationPoint Attributes

The only configurable NavigationPoint attribute that should be modified is bOneWayPath. bOneWayPath can be set to true so that paths will only be valid in the direction the NavigationPoint is facing. Turn on the bDirectional attribute of the NavigationPoint to adjust the direction it faces.

Special Purpose NavigationPoints

Several special purpose NavigationPoints exist to provide tactical or game specific positions or to provide support for special movement modes such as using translocators and jumpboots. Game specific NavigationPoints will be described in the section of this document devoted to that game type.

PlayerStarts specify allowed spawning locations for players and bots. There are two relevant configurable attributes in PlayerStarts. The TeamNumber attribute specifies which team is allowed to spawn at that PlayerStart in teamgames where team specific PlayerStarts are enforced. The bEnabled attribute, which is true by default, can be toggled to enable or disable the PlayerStart by triggering the PlayerStart.

AmbushPoints are used to specify good camping spots. They are directional and should be pointed in the direction the bot should be looking while using that AmbushPoint. AmbushPoints have two configurable attributes, SightRadius and bSniping. SightRadius specifies how far out the bot should be looking for enemies when camped at the AmbushPoint. bSniping specifies that bots using this ambushpoint should stay at this point and snipe after acquiring an enemy, rather than chasing after the enemy.

DefensePoints are a subclass of AmbushPoint used in team games. DefensePoints have three additional configurable attributes, Team, Priority, and FortTag. The Team attribute specifies which team should use this defensepoint (0=Red, 1=Blue, 2=Green, 3=Gold). The Priority attribute is used in team games to determine which DefensePoints will be manned first (higher priorities are manned earlier). The FortTag attribute is used in Assault games to associate a defensepoint with a particular FortStandard.

BlockedPaths are used to keep bots from attempting to follow routes which are initially blocked (such as a bridge which must be lowered). . When triggered, the BlockedPath is unblocked. Once unblocked, a BlockedPath cannot be re-blocked. If using a BlockedPath, make sure that there aren't any path connections which bypass the BlockedPath and render it useless. AS-Mazon has some good examples of the use of BlockedPaths.

TranslocDests are a special type of LiftCenter which are not associated with a mover. TranslocDests are used to define places that bots can use a translocator to cut a route short. A lifttexit should be placed at the spot where the bot should stand a use his translocator, and a TranslocDest should be placed where the Translocator Target should be thrown. Another liftexit should be placed near the TranslocDest, as an "exit" from this "lift". The LiftExits and the TranslocDest should be given the same LiftTag.

Bots will assume that any LiftExit with the same LiftTag as a TranslocDest can be directly reached from the TranslocDest, without any special action on the bot's part. If the bot must use the translocator to get from the TranslocDest to one of the LiftExits, replace that LiftExit with a TranslocStart.

JumpSpots are similar to TranslocDests, and are also placed in conjunction with LiftExits all given the same LiftTag. Bots understand that in low gravity areas, or in JumpMatch, or if they have JumpBoots, they can also jump to reach JumpSpots. In addition, if the bImpactJump attribute of the JumpSpot is true, higher skill bots will impact jump (using the impact hammer) to reach the JumpSpot. If the bAlwaysAccel attribute is true, bots will use air control to reach the JumpSpot (try this only if they are failing without it).

Teleporters send any pawn which touches them instantly to their destination teleporter, as specified by their URL attribute. If the URL attribute is empty, the teleporter acts only as a teleporter destination. If it contains the same string as the tag of another teleporter in the level, that teleporter will be the destination. If it contains a string in the form of LevelName/TeleporterName, it will teleport to a different level on this server (single player only). If it contains a string in the form of Unreal://Server.domain.com/LevelName/TeleporterName, it will teleport to a different server on the net.

If a teleporter's bEnabled attribute is false, then it will not teleport pawns which touch it, although it can still act as a teleporter destination. The bEnabled attribute is toggled by triggering the teleporter. If the bChangesYaw attribute is true, pawns arriving at this teleporter will have their yaw changed to the teleporter's yaw. If the bChangesVelocity attribute is true, pawns arriving at this teleporter will have their velocity set to the teleporter's TargetVelocity.

Tweaking and Debugging the Navigation Network

After placing and "defining" the navigation network, the level designed should tweak and debug it by watching bots play the level. The designer should the game as a spectator, and add first one and then later several bots to the level. The designer can watch them play, advancing through the bot cameras using the fire button, and looking for problem areas. If the bot currently being viewed seems to be acting strangely, using the console command verbose will indicate what it is thinking. After the play session, reviewing the log file may also provide insight to problems.

If the bots don't seem to understand how to get to a certain destination, the designer can use the rememberspot and showpath console commands to look for breaks in the navigation network. When the rememberspot command is used, the current location is saved. Subsequent showpath commands will cause the best visible NavigationPoint on the path to the remembered location to become visible. If no NavigationPoint becomes visible, there is no valid path to the remembered location.

If a player cannot fit in the position specified by a PlayerStart, then the player cannot properly enter the game and will either wander as a spectator or the game will crash. The log file for that play session will have information on which PlayerStart caused the failure.

UT Game Types

The Unreal Tournament team games require special actors to be placed in the level.

Domination

Domination requires ControlPoints, which are a type of NavigationPoint, to be placed at strategic locations in the level. As with all NavigationPoints, these must not be placed too close to another navigation point, and they must be placed at ground level or bots will be confused by them.

ControlPoints have several editable attributes of interest. When a player gains control of a ControlPoint (by touching it), the optional event related to the player's team is triggered. These events are specified by the RedEvent, BlueEvent, GoldEvent, and GreenEvent attributes. The bSelfDisplayed attribute specifies whether the ControlPoint mesh (which depends on which team controls it) is visible. The PointName attribute gives a human readable name to the ControlPoint. The ControlSound attribute specifies the sound to be played when control of the ControlPoint changes.

Capture the Flag

Capture the Flag requires FlagBases, which are a type of NavigationPoint to specify the home location of the flag for each CTF team. There can only be two CTF teams, and each can only have one FlagBase. The team attribute of the FlagBase specifies to which team the FlagBase is associated, with 0=Red, and 1=Blue.

AlternatePaths are used to indicate alternate routes that bots can use to enter an opponent's base. The AlternatePath's team attribute should be the same as the team of the FlagBase for which the AlternatePath is pointing out a route. The AlternatePath's SelectionWeight is used to modify the likelihood of bots using that path. Bots use AlternatePaths by first moving along the shortest route to the AlternatePath they have chosen, and then moving along the shortest route from their to the FlagBase. If the AlternatePath is set up so that the shortest route to the AltermatePath involves running right by the FlagBase, bots will do that (a bad thing!). The location of AlternatePaths may need to be adjusted to provide the desired results. AlternatePaths with the bReturnOnly flag set true are used by bots with the same team number returning to their base with a flag.

Assault

The FortStandard is used to define the objectives in the Assault map. There can be multiple FortStandards in a map. The bFinalFort attribute if true specifies that when the FortStandard is destroyed, the level is completed even if there are other FortStandards still active. The DefensePriority attribute specifies the order in which the FortStandards should be defended, with the highest DefensePriority FortStandards defended first. The NearestPathNodeTag attribute should always be used to provide bots a hint about how to get to the FortStandard. Set it to the tag of the nearest reachable PathNode. The optional FallBackFort attribute specifies which fort defenders should fallback to if the FortStandard is destroyed (set the FallBackFort to the tag of the desired FortStandard). The bTriggerOnly attribute specifies that the FortStandard should be triggered (using a trigger or by touching it) rather than shot.

The bSelfDisplayed attribute specifies that the FortStandard is visible (using its mesh). This is typically turned off and the FortStandard is displayed with level geometry. The bFlashing attribute specifies that the FortStandard should flash when it is damaged. The bSayDestroyed attribute specifies that bots should announce when they have destroyed this FortStandard (turn this off if the FortStandard marks a strategic location, and not a visible objective). If the DestroyedMessage is not empty, it will be displayed on everyone's HUD when the FortStandard is destroyed. The DamageEvent[] and DamageEventThreshold[] arrays are used to specify events which occur when the FortStandard has incurred specific amounts of damage.

The ChargeDist and bForceRadius attributes are advanced AI tweaks used to determine how aggressively bots will go after a FortStandard, when they feel they don't have adequate backup.

One of the FortStandards in the level should have the DefenseTime attribute (the total time the base needs to be defended) set. Also, one FortStandard should have the EndCamTag attribute (the tag of the spectatorcam to use when the game ends).

The TeamCannon can be placed in Assault levels to support defenders. The MinigunCannon is a minigun version of the TeamCannon.

Every Assault level must have an AssaultInfo somewhere in it. The AssaultInfo contains the text (in the ObjDesc[] array) and screenshots (in the ObjShots[] array) which describe the objectives for the level. The NumObjShots should be se to the number of text/screenshot elements.

The AssaultRandomizer can be used to force bot attackers to vary their entry routes randomly. Place an AssaultRandomizer in a spot along the shortest path, making sure there are no connections around it along that path. Set the ToggledCost attribute to an appropriate value to increase the distance cost of that path. The use a trigger to toggle the AssaultRandomizer on and off as desired, causing the path to appear longer or shorter. Never use a negative value for the ToggledCost.

The Level Info

The LevelInfo contains several properties which should be set to describe the level, including the Title string, the Author string, and the IdealPlayerCount string.

Import a screenshot and set it as the ScreenShot texture. Your preview screenshot must be a 256 x 256 pixel, 256 color .PCX or .BMP file. In UnrealEd select Textures in the Browser window and then click the Import button to import your screenshot. A file dialog will pop up. Browse to the location where your preview is stored and select it, then click the OK button. The Import Texture dialog will pop up. In the "Name:" field enter "screenshot" and in the "Package:" field enter "MyLevel". Uncheck the "Generate MipMaps" option and then click the OK Button. After UnrealEd works for a moment you should see the "MyLevel" package displayed in the browser with your preview screenshot shown in the browser texture window. Go to Level Properties from the Ued's drop down menus and there's a field called "Screenshot" (or something like that); you need to click on your newly created textured screenshot in the Browser window to have the name come up] Rebuild and save your map. (Thanks Steve Keene for this explanation.)

When you run UT and select your map (when starting a practice session or network game) you should see your screenshot displayed just as it does with all of the maps that came with UT.

RecommendedEnemies, RecommendedTeammates, and the LevelEnterText are not used.

The LevelInfo is the default ZoneInfo for zones that don't have their own ZoneInfo. See the section on ZoneInfos below.

Trigger

The Trigger actor is used to trigger events. When a Trigger is activated, it broadcasts its event to all other actors in the level. Any actors whose tag matches this event will be triggered.

The TriggerType of a Trigger specifies what situations will cause a trigger to activate. The possible settings of TriggerType are

TT_PlayerProximity Trigger is activated by player (or bot) proximity.
TT_PawnProximity Trigger is activated by any pawn's proximity.
TT_ClassProximity Trigger is activated by actor of the class specified by the Trigger attribute ClassProximityType.
TT_AnyProximity Trigger is activated by any actor in proximity.
TT_Shoot, Trigger is activated by player shooting it. The optional DamageThreshold attribute specifies the minimum damage required for triggering (instantaneous, not cumulative).

The attribute ReTriggerDelay specifies the minimum time before a trigger can be triggered again. The bTriggerOnceOnly attribute, when true, specifies that the trigger should only activated once and then go dormant.

There are several possible states for the Trigger actor. The desired state is set using the InitialState attribute (in the Object section of the Trigger properties). The alternate states are used for Trigger actors that are turned on or off by other triggers, in conjunction with the bInitiallyActive property. If bInitiallyActive is false, the Trigger will be disabled initially. The possible states for the Trigger actor are:

NormalTrigger Triggering the Trigger has no effect.
OtherTriggerToggles When triggered, the Trigger will toggle its bInitiallyActive property on and off.
OtherTriggerTurnsOn When triggered, the Trigger will turn be come active.
OtherTriggerTurnsOff When triggered, the Trigger will turn be come inactive.

RepeatTriggerTime, if set to a value greater than zero, causes the trigger to send out its event at an interval of RepeatTriggerTime seconds while the triggering actor remains within the trigger’s radius.

Special Trigger Types

The TimedTrigger is not triggered by being touched like other triggers. Rather, it triggers at a fixed interval after the level starts, specified by its DelaySeconds attribute. If its bRepeating attribute is true, the TimedTrigger will continue to trigger at every DelaySeconds interval.

The TeamTrigger is only activated by pawns which do not belong to the team specified by its Team attribute.

Triggers

Classes which are subclassed from Triggers, but are not subclassed from Trigger, are recipients rather than sources of trigger events.

The SpecialEvent has several possible states. The desired state is set using the InitialState attribute (in the Object section of the SpecialEvent properties).

DisplayMessage Just displays the message in the Message attribute.
DamageInstigator Damages the instigator who triggered this event. The Damage attribute specifies the amount of damage. The DamageType and DamageString attributes are also relevant for this state.
KillInstigator Kills the instigator, using the DamageString for his death message if the DamageType is SpecialDamage.
PlaySoundEffect Plays the sound specified by the Sound attribute at the SpecialEvent's location.
PlayersPlaySoundEffect All players play this sound effect at their location on the client side (so they hear it at full volume).
PlayAmbientSoundEffect Places the SpecialEvent's AmbientSound on the instigating player.
PlayerPath Sends the instigating actor on a spline path through the level as specified by InterpolationPoints placed in the level.

If the Message string is not empty, it will be sent to the instigating player, unless bBroadcast is true in which case it will be broadcast to all players. This will happen in any SpecialEvent state.

TBD: TriggerLight, DistanceViewTrigger, Kicker, Dispatcher, Counter

ZoneInfos

This section describes the attributes of ZoneInfos which are relevant to gameplay. For more information on the importance of properly zoning your level for rendering performance, review Zones.htm. Every zone can optionally include a ZoneInfo which specifies special attributes of that zone. Zones with no ZoneInfo in them use the LevelInfo's zon attributes.

There are several pre-defined ZoneInfo classes which should be used when possible, including WaterZones, LavaZones, and SlimeZones. The relevant attributes for these ZoneInfo classes are already properly set. While any zone can be filled with water simply by setting its bWaterZone attribute to true, the zone will not have all the normal characteristics of WaterZones, such as entry and exit splashes.

Several ZoneInfo attributes affect physics within the zone. These include ZoneGravity (for which only the Z component is relevant), ZoneGroundFriction (used for walking), ZoneFluidFriction (used for swimming in water zones), ZoneVelocity (constant velocity added to moving actors in this zone), ZoneTerminalVelocity (which specifies the maximum falling velocity), and bWaterZone (which causes the zone to be filled with water if true). If a zone has a ZoneVelocity, the bMoveProjectiles attribute specifies whether this velocity should be imparted to projectiles and effects.

Zones with bWaterZone true can also specify an EntrySound, an ExitSound, an EntryActor (such as a splash effect), and an ExitActor.

Zones can be set to damage actors that enter them by setting the bPainZone attribute to true, and specifying a DamagePerSec value and a DamageType. Setting the bDestructive attribute to true will prevent fragments and gibs from hanging around in the zone, while settingthe bNoInventory attribute to true will prevent dropped inventory items from hanging around in the zone. The actual damage inflicted on a pawn depends on the DamagePerSec value and how much of the pawn is immersed in the zone. If the DamageType is SpecialDamage, then the DamageString will be used to describe deaths.

Zones with bKillZone set to true will instantly kill any pawn that enter them. Pawns will not take damage in zones with bNeutralZone set to true.

The ZonePlayerEvent is triggered whenever a player enters the zone.

The ZoneName (in the LocationStrings section of the ZoneInfo properties) is used to identify the location of teammates on the scoreboard or when giving orders to bots. In large zones, a level designer can place LocationID actors in the zone to provide a finer granularity of location descriptions. The CollisionRadius of the LocationID (in world units) determines the area in which the LocationID's LocationName will supercede the zone's ZoneName.

The ZoneTag is used to tag a zone which is to be triggered by a ZoneTrigger. WarpZones can be triggered to sequence through an array of destinations specified in their properties. Other zones will toggle the bPainZone attribute on and off when triggered.

The ViewFog and ViewFlash properties (in the ZoneLight section of the ZoneInfo properties) allow the level designer to change the player’s display color/fogging while the player is in that zone. ViewFog is used to color the screen. It is a vector whose components are RGB values between 0 and 1.

As ViewFog increases the brightness of the screen, ViewFlash should be used to keep it from over-brightening. ViewFlash is a vector whose components should be between 0 and –1 (for example (-0.5, -0.5, -0.5). It reduces the brightness of the screen. Typically, all the components will have the same value, which should have a magnitude about the same as the average magnitude of the ViewFog components to keep the screen from changing brightness.

Special Zone Types

When a player enters a TeleporterZone, he is teleported by the associated teleporter (specified by the TeleporterZone’s TeleporterTag).

TBD: PressureZone, VacuumZone, WarpZone

AI Difficulty Differences

Unreal Tournament has 8 AI skill levels, along with a continuous range of intermediate skill levels. Skill levels 0 to 3 are called "novice" skills, because bots at these skill levels move more slowly than players and their weapons do less damage than player weapons. Bots with skill levels between 4 and 7 move at the same speed as players and their weapons do the same amount of damage.

Lower skill bots turn more slowly, and take longer to acquire an opponent. They also have worse peripheral vision. Higher skill bots have better aim, and do a better job of leading opponents. Higher skill bots are also better able to strafe, or to move toward an objective while firing at an enemy at the same time. Low skill bots move much more slowly when strafing. Higher skill bots are less disoriented when hit, and tend to fire their weapons faster (although never faster than players can).

High skill (non-novice) bots also understand the special moves with weapons, including the shock rifle combo move, the sniper rifle headshot, and impact jumping with the impact hammer.

Console commands useful for tweaking levels

These commands can be typed into the console.

  • PlayersOnly Only player actors are ticked. Everything else in the level is frozen in place.
  • AddBots n Adds n bots to the level.
  • ViewClass xxx View the game from the point of view of a member of class "xxx". Successive executions of this function will iterate through the class. For example, ViewClass Bot will show you the game from the point of view of a Bot in the level, if there is one. If you are a spectator, you can viewclass any bot or player in the level. If you are on a team in a team game, you can only viewclass teammates.
  • CheatView xxx This is used to viewclass bots on the opposing team in a single player game.
  • Verbose Shows you what the bot you are currently viewclassing is thinking.
  • KillAll xxx Destroys all actors of class xxx (including subclasses). For example, KillAll Inventory will remove all inventory, including all weapons and pickups..
  • Fly Allows you to fly around the level.
  • Walk Returns you to the normal walking state.
  • Ghost Allows you to fly around the level and go through walls. While ghosting, you cannot pick up any items.
  • Loaded Gives you all the UT weapons except for the Redeemer.
  • AllAmmo Gives you 999 ammo for all the weapons you have.
  • Invisible b With b=1 makes you invisible, while b=0 makes you visible.
  • God Toggles god mode.
  • BehindView b Toggles your view from first person (b=0) to third person (b=1).
  • SloMo f Changes the rate of time in the game. 1.0 is normal speed. 2.0 is twice normal speed. and 0.2 is one fifth normal speed.
  • KillPawns Removes all pawns from the game.
  • Summon xxx Adds an actor of class ‘xxx’ right in front of you. This can be anything (a weapon, ammo, a creature, etc.). By default, the class is assumed to be in the botpack package. If it is in another package, you must prefix the package name, e.g. 'summon unrealshare.vase'.
  • RememberSpot Remember your current location (see ShowPath below).
  • ShowPath Show the recommended path back to location remembered by RememberSpot.

End


AI Difficulty Differences

by: Steven Polge
http://www.epicgames.com/

Unreal Tournament has 8 AI skill levels, along with a continuous range of intermediate skill levels. Skill levels 0 to 3 are called "novice" skills, because bots at these skill levels move more slowly than players and their weapons do less damage than player weapons. Bots with skill levels between 4 and 7 move at the same speed as players and their weapons do the same amount of damage.

Lower skill bots turn more slowly, and take longer to acquire an opponent. They also have worse peripheral vision. Higher skill bots have better aim, and do a better job of leading opponents. Higher skill bots are also better able to strafe, or to move toward an objective while firing at an enemy at the same time. Low skill bots move much more slowly when strafing. Higher skill bots are less disoriented when hit, and tend to fire their weapons faster (although never faster than players can).

High skill (non-novice) bots also understand the special moves with weapons, including the shock rifle combo move, the sniper rifle headshot, and impact jumping with the impact hammer.


Assault

by: Steven Polge
http://www.epicgames.com/

The FortStandard is used to define the objectives in the Assault map. There can be multiple FortStandards in a map. The bFinalFort attribute if true specifies that when the FortStandard is destroyed, the level is completed even if there are other FortStandards still active. The DefensePriority attribute specifies the order in which the FortStandards should be defended, with the highest DefensePriority FortStandards defended first. The NearestPathNodeTag attribute should always be used to provide bots a hint about how to get to the FortStandard. Set it to the tag of the nearest reachable PathNode. The optional FallBackFort attribute specifies which fort defenders should fallback to if the FortStandard is destroyed (set the FallBackFort to the tag of the desired FortStandard). The bTriggerOnly attribute specifies that the FortStandard should be triggered (using a trigger or by touching it) rather than shot.

The bSelfDisplayed attribute specifies that the FortStandard is visible (using its mesh). This is typically turned off and the FortStandard is displayed with level geometry. The bFlashing attribute specifies that the FortStandard should flash when it is damaged. The bSayDestroyed attribute specifies that bots should announce when they have destroyed this FortStandard (turn this off if the FortStandard marks a strategic location, and not a visible objective). If the DestroyedMessage is not empty, it will be displayed on everyone´s HUD when the FortStandard is destroyed. The DamageEvent[] and DamageEventThreshold[] arrays are used to specify events which occur when the FortStandard has incurred specific amounts of damage.

The ChargeDist and bForceRadius attributes are advanced AI tweaks used to determine how aggressively bots will go after a FortStandard, when they feel they don´t have adequate backup.

One of the FortStandards in the level should have the DefenseTime attribute (the total time the base needs to be defended) set. Also, one FortStandard should have the EndCamTag attribute (the tag of the spectatorcam to use when the game ends).

The TeamCannon can be placed in Assault levels to support defenders. The MinigunCannon is a minigun version of the TeamCannon.

Every Assault level must have an AssaultInfo somewhere in it. The AssaultInfo contains the text (in the ObjDesc[] array) and screenshots (in the ObjShots[] array) which describe the objectives for the level. The NumObjShots should be se to the number of text/screenshot elements.

The AssaultRandomizer can be used to force bot attackers to vary their entry routes randomly. Place an AssaultRandomizer in a spot along the shortest path, making sure there are no connections around it along that path. Set the ToggledCost attribute to an appropriate value to increase the distance cost of that path. The use a trigger to toggle the AssaultRandomizer on and off as desired, causing the path to appear longer or shorter. Never use a negative value for the ToggledCost.


Capture the Flag

by: Steven Polge
http://www.epicgames.com/

Capture the Flag requires FlagBases, which are a type of NavigationPoint to specify the home location of the flag for each CTF team. There can only be two CTF teams, and each can only have one FlagBase. The team attribute of the FlagBase specifies to which team the FlagBase is associated, with 0=Red, and 1=Blue.

AlternatePaths are used to indicate alternate routes that bots can use to enter an opponent´s base. The AlternatePath´s team attribute should be the same as the team of the FlagBase for which the AlternatePath is pointing out a route. The AlternatePath´s SelectionWeight is used to modify the likelihood of bots using that path. Bots use AlternatePaths by first moving along the shortest route to the AlternatePath they have chosen, and then moving along the shortest route from their to the FlagBase. If the AlternatePath is set up so that the shortest route to the AltermatePath involves running right by the FlagBase, bots will do that (a bad thing!). The location of AlternatePaths may need to be adjusted to provide the desired results. AlternatePaths with the bReturnOnly flag set true are used by bots with the same team number returning to their base with a flag.


Domination

by: Steven Polge
http://www.epicgames.com/

Domination requires ControlPoints, which are a type of NavigationPoint, to be placed at strategic locations in the level. As with all NavigationPoints, these must not be placed too close to another navigation point, and they must be placed at ground level or bots will be confused by them.

ControlPoints have several editable attributes of interest. When a player gains control of a ControlPoint (by touching it), the optional event related to the player´s team is triggered. These events are specified by the RedEvent, BlueEvent, GoldEvent, and GreenEvent attributes. The bSelfDisplayed attribute specifies whether the ControlPoint mesh (which depends on which team controls it) is visible. The PointName attribute gives a human readable name to the ControlPoint. The ControlSound attribute specifies the sound to be played when control of the ControlPoint changes.


Console commands useful for tweaking levels

by: Steven Polge
http://www.epicgames.com/

These commands can be typed into the console.

  • PlayersOnly Only player actors are ticked. Everything else in the level is frozen in place.

  • AddBots n Adds n bots to the level.

  • ViewClass xxx View the game from the point of view of a member of class "xxx". Successive executions of this function will iterate through the class. For example, ViewClass Bot will show you the game from the point of view of a Bot in the level, if there is one. If you are a spectator, you can viewclass any bot or player in the level. If you are on a team in a team game, you can only viewclass teammates.

  • CheatView xxx This is used to viewclass bots on the opposing team in a single player game.

  • Verbose Shows you what the bot you are currently viewclassing is thinking.

  • KillAll xxx Destroys all actors of class xxx (including subclasses). For example, KillAll Inventory will remove all inventory, including all weapons and pickups..

  • Fly Allows you to fly around the level.

  • Walk Returns you to the normal walking state.

  • Ghost Allows you to fly around the level and go through walls. While ghosting, you cannot pick up any items.

  • Loaded Gives you all the UT weapons except for the Redeemer.

  • AllAmmo Gives you 999 ammo for all the weapons you have.

  • Invisible b With b=1 makes you invisible, while b=0 makes you visible.

  • God Toggles god mode.

  • BehindView b Toggles your view from first person (b=0) to third person (b=1).

  • SloMo f Changes the rate of time in the game. 1.0 is normal speed. 2.0 is twice normal speed. and 0.2 is one fifth normal speed.

  • KillPawns Removes all pawns from the game.

  • Summon xxx Adds an actor of class ‘xxx’ right in front of you. This can be anything (a weapon, ammo, a creature, etc.). By default, the class is assumed to be in the botpack package. If it is in another package, you must prefix the package name, e.g. ´summon unrealshare.vase´.

  • RememberSpot Remember your current location (see ShowPath below).

  • ShowPath Show the recommended path back to location remembered by RememberSpot.


Creating the Navigation Network

by: Steven Polge
http://www.epicgames.com/

Unreal Tournament bots use a system of waypoints to navigate the level. Using waypoints allows UT to minimize the CPU cycles used by the AI, and gives level designers maximum control over how the AI navigates their levels.

These waypoints are defined by placing actors which are subclassed from NavigationPoint in the level. This includes actors such as PlayerStarts and Teleporters which designers will place to make their level playable. Certain NavigationPoints, such as InventorySpots and WarpZoneMarkers are automatically placed when the designer "defines" the paths (described below). Other NavigationPoints are intended for Unreal I style single player situations and are not used at all in UT. These include AlarmPoints, ButtonMarkers, PatrolPoints, QueenDests, SpawnPoints, Transporters, and TriggerMarkers.

Once the level geometry is complete, the level designer should fully map the level into the navigation network using PathNodes. Place PathNodes at intersections and turns so that there is as much clearance as possible from corners (at least 50 world units if possible). Paths need a line of sight to each other, clear to the width of the maximum width (2 * collisionradius) of creatures which will use this path. PathNodes should not be placed more than 700 units apart. Since PlayerStarts and Inventory will be placed on the navigation network, the designer can (and should) not place PathNodes where these other NavigationPoints can substitute. On stairs and ramps, the PathNodes should only be 350 units apart. The objective should be to use a minimum number of PathNodes to completely cover a level.

Version 402 of Unreal Tournament has an automatic PathNode generator which will do part of the work of placing paths automatically. It will attempt to cover the level with paths, but will not place special NavigationPoints such as playerstarts, liftcenters, etc.. To use the automatic PathNode generator, open your level in UnrealEd. Select the Window menu, and from it the log. At the prompt type ´Paths Build´ (no quotes). This will take 5 to 10 minutes for a typical level.

To navigate around the level, bots will first find the nearest reachable NavigationPoint, and move to it. They will then move toward their destination, going from NavigationPoint to NavigationPoint. It is important that some NavigationPoint is reachable (there are no obstructions in the way) from any location a bot may reasonably get to in the level. If a bot can´t find a valid path, either because it can´t find a way to get on the network, or there is no valid way to get from the network to its destination, or the path on the network is broken, then the bot will wander (walking) around its current area.

The final step in setting up the navigation network is performing a PATHS DEFINE. This can be done by typing PATHS DEFINE into the UnrealEd console, or pressing the "Paths Define" button in the lighting section of the rebuild window. The designer can examine the network generated in any of the UnrealEd world view windows by selecting "Show Paths" from that window´s "View" menu. NavigationPoints which are successfully connected will have either blue or red lines between them. Bots will use either blue or red paths, but blue paths are preferable - they indicate a cleaner, more obstruction free path. Each time geometry is changed or NavigationPoints are added or moved (including inventory, since paths are generated from inventory items), a PATHS DEFINE should be performed.

There are several common problems that result from assumptions and approximations made by the AI to minimize CPU overhead. Make sure that all NavigationPoints are separated by at least 50 world units. If two pathnodes are too close together, a bot may get stuck on them. The editor log window will display warnings during a PATHS DEFINE if paths are too close together. This problem commonly occurs with InventorySpots, which are automatically placed near all inventory items. Don´t place PathNodes too near to inventory.

In some situations, bots may get stuck on the edge of a ledge where it runs into a wall. This occurs because of a threshold problem. Bots won´t jump off ledges until the angle of their destination is greater than 45 degrees from the ledge direction. If they run into a wall right around this threshold, they may get confused. The solution is to adjust the NavigationPoint they were trying to reach, or add an intermediate PathNode.

Bots will have problems if the NavigationPoints are too high off the ground. Make sure that the NavigationPoint is no more than 1.5x the bot´s collisionheight off the ground. This will normally be the case automatically, but in a few situations (such as very steep ramps), the level designer may need to manually adjust the Z position of the NavigationPoint.

PathNodes for the bots to use while swimming must be in the water. Placing paths above the water´s surface will result in bots bobbing at that spot, attempting unsuccessfully to levitate to the PathNode´s location.

WarpZones should be at least 70 units deep to allow the AI to handle them properly.


NavigationPoint Attributes

by: Steven Polge
http://www.epicgames.com/

The only configurable NavigationPoint attribute that should be modified is bOneWayPath. bOneWayPath can be set to true so that paths will only be valid in the direction the NavigationPoint is facing. Turn on the bDirectional attribute of the NavigationPoint to adjust the direction it faces.


Special Purpose NavigationPoints

by: Steven Polge
http://www.epicgames.com/

Several special purpose NavigationPoints exist to provide tactical or game specific positions or to provide support for special movement modes such as using translocators and jumpboots. Game specific NavigationPoints will be described in the section of this document devoted to that game type.

PlayerStarts specify allowed spawning locations for players and bots. There are two relevant configurable attributes in PlayerStarts. The TeamNumber attribute specifies which team is allowed to spawn at that PlayerStart in teamgames where team specific PlayerStarts are enforced. The bEnabled attribute, which is true by default, can be toggled to enable or disable the PlayerStart by triggering the PlayerStart.

AmbushPoints are used to specify good camping spots. They are directional and should be pointed in the direction the bot should be looking while using that AmbushPoint. AmbushPoints have two configurable attributes, SightRadius and bSniping. SightRadius specifies how far out the bot should be looking for enemies when camped at the AmbushPoint. bSniping specifies that bots using this ambushpoint should stay at this point and snipe after acquiring an enemy, rather than chasing after the enemy.

DefensePoints are a subclass of AmbushPoint used in team games. DefensePoints have three additional configurable attributes, Team, Priority, and FortTag. The Team attribute specifies which team should use this defensepoint (0=Red, 1=Blue, 2=Green, 3=Gold). The Priority attribute is used in team games to determine which DefensePoints will be manned first (higher priorities are manned earlier). The FortTag attribute is used in Assault games to associate a defensepoint with a particular FortStandard.

BlockedPaths are used to keep bots from attempting to follow routes which are initially blocked (such as a bridge which must be lowered). . When triggered, the BlockedPath is unblocked. Once unblocked, a BlockedPath cannot be re-blocked. If using a BlockedPath, make sure that there aren´t any path connections which bypass the BlockedPath and render it useless. AS-Mazon has some good examples of the use of BlockedPaths.

TranslocDests are a special type of LiftCenter which are not associated with a mover. TranslocDests are used to define places that bots can use a translocator to cut a route short. A lifttexit should be placed at the spot where the bot should stand a use his translocator, and a TranslocDest should be placed where the Translocator Target should be thrown. Another liftexit should be placed near the TranslocDest, as an "exit" from this "lift". The LiftExits and the TranslocDest should be given the same LiftTag.

Bots will assume that any LiftExit with the same LiftTag as a TranslocDest can be directly reached from the TranslocDest, without any special action on the bot´s part. If the bot must use the translocator to get from the TranslocDest to one of the LiftExits, replace that LiftExit with a TranslocStart.

JumpSpots are similar to TranslocDests, and are also placed in conjunction with LiftExits all given the same LiftTag. Bots understand that in low gravity areas, or in JumpMatch, or if they have JumpBoots, they can also jump to reach JumpSpots. In addition, if the bImpactJump attribute of the JumpSpot is true, higher skill bots will impact jump (using the impact hammer) to reach the JumpSpot. If the bAlwaysAccel attribute is true, bots will use air control to reach the JumpSpot (try this only if they are failing without it).

Teleporters send any pawn which touches them instantly to their destination teleporter, as specified by their URL attribute. If the URL attribute is empty, the teleporter acts only as a teleporter destination. If it contains the same string as the tag of another teleporter in the level, that teleporter will be the destination. If it contains a string in the form of LevelName/TeleporterName, it will teleport to a different level on this server (single player only). If it contains a string in the form of Unreal://Server.domain.com/LevelName/TeleporterName, it will teleport to a different server on the net.

If a teleporter´s bEnabled attribute is false, then it will not teleport pawns which touch it, although it can still act as a teleporter destination. The bEnabled attribute is toggled by triggering the teleporter. If the bChangesYaw attribute is true, pawns arriving at this teleporter will have their yaw changed to the teleporter´s yaw. If the bChangesVelocity attribute is true, pawns arriving at this teleporter will have their velocity set to the teleporter´s TargetVelocity.


Tweaking and Debugging the Navigation Network

by: Steven Polge
http://www.epicgames.com/

After placing and "defining" the navigation network, the level designed should tweak and debug it by watching bots play the level. The designer should the game as a spectator, and add first one and then later several bots to the level. The designer can watch them play, advancing through the bot cameras using the fire button, and looking for problem areas. If the bot currently being viewed seems to be acting strangely, using the console command verbose will indicate what it is thinking. After the play session, reviewing the log file may also provide insight to problems.

If the bots don´t seem to understand how to get to a certain destination, the designer can use the rememberspot and showpath console commands to look for breaks in the navigation network. When the rememberspot command is used, the current location is saved. Subsequent showpath commands will cause the best visible NavigationPoint on the path to the remembered location to become visible. If no NavigationPoint becomes visible, there is no valid path to the remembered location.

If a player cannot fit in the position specified by a PlayerStart, then the player cannot properly enter the game and will either wander as a spectator or the game will crash. The log file for that play session will have information on which PlayerStart caused the failure.


Adding Support for Lifts

by: Steven Polge
http://www.epicgames.com/

There are two special NavigationPoint classes used to help bots understand how to use lifts, LiftCenters and LiftExits. Give the lift a unique tag. Place a LiftCenter on the lift, and set its LiftTag attribute to be the tag of the lift. At each exit from the lift, far enough away so that bots standing at that spot won´t interfere with the lift, add a LiftExit. Each LiftExit should have its LiftTag set to the tag of the lift.

The default state for movers is BumpOpenTimed. Do not use this state for lifts! Bots misinterpret movers that are BumpOpenTimed as being doors. Instead, use the StandOpenTimed state for most lifts. Bots will also understand triggered lifts (TriggerOpenTimed, TriggerToggle, etc.). In many cases, they will use triggered lifts without any further help. However, for certain complex situations, such as when a delayed dispatcher is used to control the lift, bots may need a hint. In these cases, set the LiftCenter´s LiftTrigger attribute to the tag of the trigger the bot should use to control this lift.

There are two other configurable LiftCenter attributes of interest. These should be modified only if absolutely necessary. MaxZDiffAdd, which defaults to 0, specifies an additional allowable difference in height between the bot and the LiftCenter for the bot to consider that LiftCenter reachable. This is useful if the bot must stand below the lift (down stairs or a ramp) while waiting for it. MaxDist2D is the maximum distance between the bot and the LiftCenter. It defaults to 400 world units.


The Level Info

by: Steven Polge
http://www.epicgames.com/

The LevelInfo contains several properties which should be set to describe the level, including the Title string, the Author string, and the IdealPlayerCount string.

Import a screenshot and set it as the ScreenShot texture. Your preview screenshot must be a 256 x 256 pixel, 256 color .PCX or .BMP file. In UnrealEd select Textures in the Browser window and then click the Import button to import your screenshot. A file dialog will pop up. Browse to the location where your preview is stored and select it, then click the OK button. The Import Texture dialog will pop up. In the "Name:" field enter "screenshot" and in the "Package:" field enter "MyLevel". Uncheck the "Generate MipMaps" option and then click the OK Button. After UnrealEd works for a moment you should see the "MyLevel" package displayed in the browser with your preview screenshot shown in the browser texture window. Go to Level Properties from the Ued´s drop down menus and there´s a field called "Screenshot" (or something like that); you need to click on your newly created textured screenshot in the Browser window to have the name come up] Rebuild and save your map. (Thanks Steve Keene for this explanation.)

When you run UT and select your map (when starting a practice session or network game) you should see your screenshot displayed just as it does with all of the maps that came with UT.

RecommendedEnemies, RecommendedTeammates, and the LevelEnterText are not used.

The LevelInfo is the default ZoneInfo for zones that don´t have their own ZoneInfo. See the section on ZoneInfos below.


Porting Unreal Maps to Unreal Tournament

by: Steven Polge
http://www.epicgames.com/

Unreal I content is automatically replaced by Unreal Tournament content if you run an Unreal I DM map with one of the Unreal Tournament gametypes. However, we recommend that you manually replace the Unreal I inventory items in your level with their UT equivalents and release an updated version of the map. Otherwise, both the Unreal I and UT versions will be loaded on the content, which will cause swapping on clients with low amounts of memory.


Trigger

by: Steven Polge
http://www.epicgames.com/

The Trigger actor is used to trigger events. When a Trigger is activated, it broadcasts its event to all other actors in the level. Any actors whose tag matches this event will be triggered.

The TriggerType of a Trigger specifies what situations will cause a trigger to activate. The possible settings of TriggerType are

TT_PlayerProximity Trigger is activated by player (or bot) proximity.
TT_PawnProximity Trigger is activated by any pawn´s proximity.
TT_ClassProximity Trigger is activated by actor of the class specified by the Trigger attribute ClassProximityType.
TT_AnyProximity Trigger is activated by any actor in proximity.
TT_Shoot, Trigger is activated by player shooting it. The optional DamageThreshold attribute specifies the minimum damage required for triggering (instantaneous, not cumulative).

The attribute ReTriggerDelay specifies the minimum time before a trigger can be triggered again. The bTriggerOnceOnly attribute, when true, specifies that the trigger should only activated once and then go dormant.

There are several possible states for the Trigger actor. The desired state is set using the InitialState attribute (in the Object section of the Trigger properties). The alternate states are used for Trigger actors that are turned on or off by other triggers, in conjunction with the bInitiallyActive property. If bInitiallyActive is false, the Trigger will be disabled initially. The possible states for the Trigger actor are:

NormalTrigger Triggering the Trigger has no effect.
OtherTriggerToggles When triggered, the Trigger will toggle its bInitiallyActive property on and off.
OtherTriggerTurnsOn When triggered, the Trigger will turn be come active.
OtherTriggerTurnsOff When triggered, the Trigger will turn be come inactive.

RepeatTriggerTime, if set to a value greater than zero, causes the trigger to send out its event at an interval of RepeatTriggerTime seconds while the triggering actor remains within the trigger’s radius.


Triggers Types

by: Steven Polge
http://www.epicgames.com/

Classes which are subclassed from Triggers, but are not subclassed from Trigger, are recipients rather than sources of trigger events.

The SpecialEvent has several possible states. The desired state is set using the InitialState attribute (in the Object section of the SpecialEvent properties).

DisplayMessage Just displays the message in the Message attribute.
DamageInstigator Damages the instigator who triggered this event. The Damage attribute specifies the amount of damage. The DamageType and DamageString attributes are also relevant for this state.
KillInstigator Kills the instigator, using the DamageString for his death message if the DamageType is SpecialDamage.
PlaySoundEffect Plays the sound specified by the Sound attribute at the SpecialEvent´s location.
PlayersPlaySoundEffect All players play this sound effect at their location on the client side (so they hear it at full volume).
PlayAmbientSoundEffect Places the SpecialEvent´s AmbientSound on the instigating player.
PlayerPath Sends the instigating actor on a spline path through the level as specified by InterpolationPoints placed in the level.

If the Message string is not empty, it will be sent to the instigating player, unless bBroadcast is true in which case it will be broadcast to all players. This will happen in any SpecialEvent state.

TBD: TriggerLight, DistanceViewTrigger, Kicker, Dispatcher, Counter


Special Trigger Types

by: Steven Polge
http://www.epicgames.com/

The TimedTrigger is not triggered by being touched like other triggers. Rather, it triggers at a fixed interval after the level starts, specified by its DelaySeconds attribute. If its bRepeating attribute is true, the TimedTrigger will continue to trigger at every DelaySeconds interval.

The TeamTrigger is only activated by pawns which do not belong to the team specified by its Team attribute.


ZoneInfos

by: Steven Polge
http://www.epicgames.com/

This section describes the attributes of ZoneInfos which are relevant to gameplay. Every zone can optionally include a ZoneInfo which specifies special attributes of that zone. Zones with no ZoneInfo in them use the LevelInfo´s zon attributes.

There are several pre-defined ZoneInfo classes which should be used when possible, including WaterZones, LavaZones, and SlimeZones. The relevant attributes for these ZoneInfo classes are already properly set. While any zone can be filled with water simply by setting its bWaterZone attribute to true, the zone will not have all the normal characteristics of WaterZones, such as entry and exit splashes.

Several ZoneInfo attributes affect physics within the zone. These include ZoneGravity (for which only the Z component is relevant), ZoneGroundFriction (used for walking), ZoneFluidFriction (used for swimming in water zones), ZoneVelocity (constant velocity added to moving actors in this zone), ZoneTerminalVelocity (which specifies the maximum falling velocity), and bWaterZone (which causes the zone to be filled with water if true). If a zone has a ZoneVelocity, the bMoveProjectiles attribute specifies whether this velocity should be imparted to projectiles and effects.

Zones with bWaterZone true can also specify an EntrySound, an ExitSound, an EntryActor (such as a splash effect), and an ExitActor.

Zones can be set to damage actors that enter them by setting the bPainZone attribute to true, and specifying a DamagePerSec value and a DamageType. Setting the bDestructive attribute to true will prevent fragments and gibs from hanging around in the zone, while settingthe bNoInventory attribute to true will prevent dropped inventory items from hanging around in the zone. The actual damage inflicted on a pawn depends on the DamagePerSec value and how much of the pawn is immersed in the zone. If the DamageType is SpecialDamage, then the DamageString will be used to describe deaths.

Zones with bKillZone set to true will instantly kill any pawn that enter them. Pawns will not take damage in zones with bNeutralZone set to true.

The ZonePlayerEvent is triggered whenever a player enters the zone.

The ZoneName (in the LocationStrings section of the ZoneInfo properties) is used to identify the location of teammates on the scoreboard or when giving orders to bots. In large zones, a level designer can place LocationID actors in the zone to provide a finer granularity of location descriptions. The CollisionRadius of the LocationID (in world units) determines the area in which the LocationID´s LocationName will supercede the zone´s ZoneName.

The ZoneTag is used to tag a zone which is to be triggered by a ZoneTrigger. WarpZones can be triggered to sequence through an array of destinations specified in their properties. Other zones will toggle the bPainZone attribute on and off when triggered.

The ViewFog and ViewFlash properties (in the ZoneLight section of the ZoneInfo properties) allow the level designer to change the player’s display color/fogging while the player is in that zone. ViewFog is used to color the screen. It is a vector whose components are RGB values between 0 and 1.

As ViewFog increases the brightness of the screen, ViewFlash should be used to keep it from over-brightening. ViewFlash is a vector whose components should be between 0 and –1 (for example (-0.5, -0.5, -0.5). It reduces the brightness of the screen. Typically, all the components will have the same value, which should have a magnitude about the same as the average magnitude of the ViewFog components to keep the screen from changing brightness.


True

True-Type Font Importing in Unreal

Jack Porter
Epic Games, Inc.
http://www.epicgames.com/

Audience: Licensees and mod-makers wanting to use Windows true-type fonts in the Unreal engine.
Last Updated: 01/25/02

Introduction

The TTF importer allows you to convert a Windows true-type font of a particular size into an Unreal font which you can then use to draw in-game text. The Unreal engine now has support for rendering anti-aliased fonts, and the TTF importer allows you to import the anti-aliasing from a Windows font.

Unreal has had the ability to import true-type fonts for use in-game since version 224, although there was a bug in the 224 font importer code which meant all the fonts you imported ended up as MS Sans Serif. Be sure you're using Unreal 225f or later, or you may have problems.

Importing Fonts into a .u File

You can import regular Unreal font textures into .u files using a #exec command, which instructs ucc make to import the font as the .u package is created. For example:

#exec Font Import File=Textures\MedFont.pcx Name=MedFont

Once the font is imported, you can refer to it as Font'MedFont' from inside UnrealScript.

To import a TTF, the true-type font first needs to be installed and accessible as a Windows font. If you've got a *.TTF file, you'll have to start by copying the font file into the Fonts control panel. Once this is done, you can import that TTF into a .u file, when ucc make creates the .u package, also by using a #exec command:

#exec new TrueTypeFontFactory Name=Tahoma30 FontName="Tahoma" Height=30 AntiAlias=1 CharactersPerPage=32

  • The Name parameter specifies the name of the font. In this case, I can refer to the font as Font'Tahoma30' from Script
  • The FontName parameter specifies the Windows name of the font to be imported. For example "Comic Sans MS", "Arial" or "Earth Normal".
  • The Height parameter is the height of the font in pixels, which I give to Windows' CreateFont() API call.
  • If AntiAlias is 1, the TTF importer requests an anti-aliased font from Windows with the ANTIALIASED_QUALITY flag to CreateFont(). If it is 0, I pass NONANTIALIASED_QUALITY. See below for limitations of importing fonts with anti-aliasing.
  • The CharactersPerPage parameter specifies the number of characters per 256x256 pixel font texture. The default is 64. The TTF importer will give you an error if it runs out of space when drawing characters on the font pages. If you get the error "Font vertical size exceeded maximum of 256", you should half the CharactersPerPage parameter.
  • Two other parameters - XPad and YPad, add extra space between characters. These default to 1. Some fonts require extra space between characters, as Windows doesn't report their actual spacing requirement correctly.

Importing Anti-aliased Fonts

I've found that Windows only honors the ANTIALIASED_QUALITY parameter to CreateFont() when the following conditions are met:

  • Running Windows NT4. I don't know why. The ANTIALIASED_QUALITY flag is undocumented.
  • Running in 16-bit or 32-bit color depth
  • Specifying a Height above a certain size

This last limitation is apparently coded into the TTF file in a table called the GASP Table. I found this program which removes the GASP table from a TTF file, and allows you to request an anti-aliased font at any font size. But with some fonts, the letter i disappears to nothing at small font sizes. Anti-aliasing looks best with large fonts.

Importing Fonts into a .utx File

Because importing the fonts requires that the font be installed and that the machine doing the importing is configured in a way which can import anti-aliased fonts, we tend to import our fonts directly into a UTX file. This way, they're imported only whenever we change or add to the fonts. To do this, you need to run UnrealEd and choose the Window|Log menu option. From the UnrealEd log window, you can type any #exec command - just type the command without the "#exec" part. For example:

new TrueTypeFontFactory PACKAGE="UWindowFonts" Name=Tahoma30 FontName="Tahoma" Height=30 AntiAlias=1 CharactersPerPage=32

The Package parameter specifies the name of the UTX package to import the font into. If you then choose Browse Textures over on the right hand side of UnrealEd, you'll be able to see the fonts you've just imported. You can then press the Save button to save the UTX texture package.

A way to automate this is to create a text file with a number of commands you would type into the log window. Here's a copy of a file called uwindowfonts.txt, which imports a number of fonts into a package called UWindowFonts.utx. To run it, I type "exec uwindowfonts.txt" from the UnrealEd log window.

new TrueTypeFontFactory PACKAGE="UWindowFonts" Name=Tahoma10
  FontName="Tahoma" Height=10 AntiAlias=0
new TrueTypeFontFactory
  PACKAGE="UWindowFonts" Name=Tahoma20 FontName="Tahoma" Height=20
  AntiAlias=1
new TrueTypeFontFactory PACKAGE="UWindowFonts" Name=Tahoma30
  FontName="Tahoma" Height=30 AntiAlias=1 CharactersPerPage=32
new
  TrueTypeFontFactory PACKAGE="UWindowFonts" Name=TahomaB10 FontName="Tahoma
  Bold" Height=10 AntiAlias=1
new TrueTypeFontFactory PACKAGE="UWindowFonts"
  Name=TahomaB20 FontName="Tahoma Bold" Height=20 AntiAlias=1 XPad=2
new
  TrueTypeFontFactory PACKAGE="UWindowFonts" Name=TahomaB30 FontName="Tahoma
  Bold" Height=30 AntiAlias=1 CharactersPerPage=32 XPad=2
new
  TrueTypeFontFactory PACKAGE="UWindowFonts" Name=UTFont12 FontName="Verdana"
  Height=12 AntiAlias=0
new TrueTypeFontFactory PACKAGE="UWindowFonts"
  Name=UTFont24 FontName="Arial Narrow" Height=24 AntiAlias=1
new
  TrueTypeFontFactory PACKAGE="UWindowFonts" Name=UTFont40 FontName="Arial Bold"
  Height=40 CharactersPerPage=32 AntiAlias=1
OBJ SAVEPACKAGE PACKAGE="UWindowFonts"
  FILE="..\Textures\UWindowFonts.utx"

The final line automates the saving of the .utx file.

Referring to Fonts in a .utx File with OBJ LOAD

Once you have a font in a UTX, there are a number of ways you can access it from Script. You can use a #exec OBJ LOAD directive to force the script compiler to load the UTX package at script compile time.

This example, from a script file in Botpack.u package, loads the AmmoCount.utx file and includes its contents inside the Botpack.u package. The Ammocount.utx file doesn't need to be distributed because its contents are included inside the .u file.

#exec OBJ LOAD FILE=Textures\Ammocount.utx PACKAGE=Botpack.Ammocount

This example loads the UTX into memory and makes the fonts it contains accessible to script, but the UTX still needs to be distributed as its contents do not get included in the .u file. Note the PACKAGE parameter is not the name of the current package being compiled - that indicates that the package should just be loaded into memory so the script compiler can refer to objects inside the package.

#exec OBJ LOAD FILE=..\Textures\UWindowFonts.utx PACKAGE=UWindowFonts

In both cases, the fonts are accessible with the Font'fontname' syntax.

Loading Fonts at Runtime from a .utx File

You can also load the fonts at runtime, using DynamicLoadObject. This is useful if you have a number of fonts you may want to use depending on resolution etc.

local Font F;
local string S;
local int FontSize;
FontSize =
  30;
S = "uwindowfonts.tahoma"$string(FontSize);
F =
  Font(DynamicLoadObject(S, class'Font'));

This is the method we use in Unreal Tournament to dynamically load fonts for the GUI and HUD.

End


Composing Music for Unreal

Alexander Brandon
abrandon@uswest.net
Straylight Productions

UPDATE

Many apologies for the lack of updates to this page. They've been long overdue, and there is much to report regarding Unreal's music. Expect to see regular updates from now on. Also stop by the Straylight site for updates concerning interactive music using the Unreal Engine as well!

Last Updated: 07/09/1999

Programs to use

There are many choices now for composing music using the Unreal Engine. Unreal, Unreal Tournament, and the Unreal Mission Pack all used MOD files, which were chosen because of small file size and excellent quality compared to MIDI based files. New developments, however, have led to new ways of music reproduction in the engine.

  • TRACKERS: Tracker programs, used to write MOD files, can be found at "Maz' Sound Tools" page (listed below), along with information about how they are used and samples to use with them. The two trackers that are most widely used are "Impulse Tracker" and "Fast Tracker 2". Both have excellent features. Try them and see which one you prefer! Note that Tracker programs are usually either shareware or freeware. They are the least expensive way to get into making music for Unreal based games.
  • DIRECTMUSIC: DirectMusic Producer, included free with DirectX 6.0, is another easy way to get into music production. DirectMusic uses a MIDI based approach to composition, letting you create your own samples much the same way as you would use tracking programs. DirectMusic, however, has numerous ways of letting you manipulate your music and change it interactively with game events. For more information contact Chanel Summers.
  • REDBOOK / STREAMED AUDIO: CD audio and other forms of streamed audio are becoming much more popular now that they don't use as much in terms of processing time. However, they take up a LOT of space, and the more channels you use and the higher quality you use, the more space is needed. A 44khz 16 bit stereo piece 4 minutes in length takes about 45 megabytes of space, and if you wish to use more channels for surround sound (such as Dolby Digital AC-3), the size doubles or even triples in size from there. However, there are many forms of compression such as ADPCM that allow you to compress a 16 bit file to 4 or 8 bit with minimal signal degradation. Compression routines can be used in programs like Sonic Foundry's "Sound Forge" .. more info can be found at www.sonic-foundry.com. Unreal's "Galaxy" sound engine can play back many different audio file formats from Redbook CD audio to streamed WAV files.
  • MP3s: For commercial games, there is a tricky situation going on. The folks who supposedly created the MP3 compression program (Fraunhofer), have put a patent on it, which says that they get part of anything sold that uses this compression. Quite a pain, but there are proceedings being held all over the world against this patent, so it will either stand or be dropped, we'll have to wait and see. For non commercial use, however, such as freeware TC and MOD distribution, MP3s can be used just fine, and "Galaxy" will play them back in Unreal.

Frequently Asked Questions

How can I play Unreal music outside of Unreal?

Try going into UnrealED, go to the texture browser, select "Music", and load the song you want (.UMX file).. then press the Export button. You will be able to export the file selected as an Impulse Tracker (.IT) file. The .IT file can be then played in WinAMP or other Windows MOD players (available at Maz' Sound Tools).

I'm trying to use Impulse Tracker files with Unreal, but they won't play. Why?

The Galaxy audio engine within Unreal does not support certain extended features of Impulse Tracker, such as New Note Actions (when you use 'instruments' instead of 'samples' in IT, for instance). However, it DOES support ping pong looping, 16 bit files, up to 32 channels (64, if you don't want sound fx playing ), and panning envelopes. No volume envelopes, though.

Can I play multiple WAV files for interactive music?

Yes. Galaxy can play up to 64 WAV files at once. Be warned however, that using more than 2 or three WAV files over 2 megs in size will slow down the system.

Did more people work on Unreal than you and Michiel Van Den Bos?

Yep! Andrew Sega contributed a song to Unreal. His nick is "necros" and he is currently working at Digital Anvil. Another contributor was Dan Gardopee, my partner and the co-founder of Straylight Productions.

Sites

  • "Maz's Sound Tools" is a great one-stop site for getting tracking programs, samples, info on soundcards, converters, and generally everything else under the sun. http://www.maz-sound.com/
  • DirectMusic Overview


Unreal Model Importing

Unreal Model Importing: The 3ds2unr Converter

Developed by Legend Entertainment (Creators of Wheel of Time)
http://www.legendent.com/
http://www.wheeloftime.com/
Programmed by David Townsend

Last Updated: 01/25/02

Tools you need

To create animated models for Unreal mods, you will need the following tools:

  1. A good 3D modelling/animation package, such as 3D Studio Max, Lightwave, SoftImage, or Alias PowerAnimator. Our converter currently only supports 3D Studio Max.
  2. A model conversion tool which converts your models from their native format (for example, the converter available here supports 3D Studio Max) to Unreal's format (Aniv*.3d, Data*.3d).
  3. UnrealEd. The beta version shipping with the game will do the job.

Required Reading

To be able to take advantage of this tool, you need to become familiar with:

  1. The contents of this document.
  2. How UnrealScript works (for writing code to control the models). See the UnrealScript Reference.
  3. How Unreal packages work, specifically how to rebuild scripts from .uc files using "Unreal.exe -make". See the Package Reference.
  4. The UnrealScript #exec commands for importing meshes, scaling them, and assigning names to animation sequences. These haven't been documented anywhere, but there are hundreds of examples in the code. See the Skaarj, Brute, and AutoMag scripts for examples.

Next, be aware that importing animations into Unreal has proven to be the trickiest aspect of Unreal content creation, because of the multiple tools that need to be used (a 3D modelling program, 3ds2unr, and UnrealEd), and because of the large number of steps that need to be followed carefully in order to successfully import and use a model in Unreal.

Files you'll deal with

For the sake of clarity, here are the files you'll be dealing with:

  • *.3ds: Your original 3D Studio file, which includes: Your model. Your animation frames. Your texture coordinates.
  • Aniv*.3d, Data*.3d: Two intermediate files generated by 3ds2unr.exe. Suitable for importing into UnrealEd.
  • *.uc: Your UnrealScript class definition, which contains #exec commands for importing your mesh. A text file, generated either by UnrealEd (when exporting a class) or by any text editor you might use to author it.
  • *.u: Your Unreal class file. A binary file containing all the data: the class and script code, the mesh, any sound effects, etc. Generated by "Unreal.exe -make"

Downloading the utility

Here is the 3D Studio to Unreal converter, including the utility (3ds2unr.exe), quick documentation (ImportingModels.doc), and the source code. The source code compiles with Microsoft Visual C++ 5.0 using Service Pack 2. We haven't tested with other compilers, versions, or service packs. The source code is unsupported and is provided as-is. Enthusiasts have permission to modify and redistribute the code on a non-commercial, not-for-profit basis.

  • Download it

Here is an example of some of the cool things people could do by modifying the source. :)

  • Make converters for other file formats, such as Lightwave, SoftImage, and Alias PowerAnimator.

Modeling

Models must be made up of a single 3D Studio object, which lives within the 256x256x256 coordinate space centered on the origin. (Setting the grid extents to –128..128 and turning on the grid is helpful here.) The model itself should be centered on the origin (0,0,0) because of how Unreal specifies the collision cylinders used to determine when objects are touching.

Models will lose some precision when imported. Specifically, X and Y coordinates are truncated to the nearest 1/8th (0.125) unit, and Z coordinates are truncated to the nearest 1/4th (0.25) unit.

One 3DS coordinate equals 6" in Unreal X and Y coordinates, or 12" in Unreal Z coordinates. You generally don’t have to worry about this scaling, as the model can be rescaled when it’s imported into Unreal.

Object polygons shouldn’t intersect. The hardware supported by Unreal gets confused when polygons intersect, resulting in an unpleasant shimmering.

If your object is a character that will be carrying a weapon that will be separately modeled, place an extra polygon (the weapon triangle) in or on the part of the character where the weapon should be. This polygon will be invisible in the game; it’s just used to sync the weapon’s position with the character’s animation.

The conversion tool will only convert objects with sequence numbers in their names (Obj01, Obj02, ...). The object name itself is meaningless; it’s the sequence numbers that count. They must begin at 01 (even if that’s the only frame!) and you can’t have any "holes" in the sequence. (Under 3D Studio 4, it was easiest to use the "Snapshot" option; I’m not sure how 3DS MAX handles this.)

Objects that won’t be animated (e.g. 3rd person weapon views) should be in their own .3DS file (e.g. save the angreal of healing as AngrealHeal.3DS).

Animation

Make sure that all animation frames stay entirely within the 256x256x256 coordinate space.

The Unreal animators are typically designing their animations for 30-35 fps playback. Then, to save memory, they shave the animations down to 15-17 fps and let Unreal do the tweening.

Objects that are animated should have a separate .3DS file for each animation sequence (Run.3DS, Walk.3DS, Shoot.3DS, etc.). You probably want a separate directory for each animating character, so that each can have it’s own Run.3DS sequence.

Texture Mapping

You still use 3D Studio to do your texture mapping. However, there are some (pretty heavy) restrictions on what will actually show up in Unreal.

The only type of texturing that has any effect is using actual texture maps – bump maps, opacity maps, specular maps, etc. are meaningless. Furthermore, the bitmaps that you use as textures should be 256x256 pixels in size, and you can’t have more than nine of them for any one model. To conserve memory, you should use as few texture maps as possible. 3DS Max V2 allows you to map part of a material to your geometry; using this feature lets you squeeze many smaller texture maps together into one big bitmap.

Our Wheel of Time characters currently use two texture maps. The angreal use only one.

Under most circumstances, the material names that you use in 3D Studio don’t matter. However, there are several pre-defined material names that you can use to get special effects when the model is imported into Unreal. The special names are:

SKIN | This texture will be assigned as the model’s Skin property in Unreal. Skin textures can be replaced easily at runtime (to show increasing damage, for example) and are the basis for Unreal’s corona effects.
TRANSLUCENT | The polygons mapped with this texture will be marked as translucent, and can have their transparency set by the program. Wheel of Time uses this to get the transparent globe on the Shield angreal.
TWOSIDED | The polygons mapped with this texture will be marked as two-sided, so the texture mapping will show up on both sides of the polygon. Wheel of Time uses this for the characters’ cloaks.
WEAPON | The polygon (there should be only one!) mapped with this texture will be marked as the weapon triangle. So it won’t be visible

Note that this naming convention applies to the material name itself; the filename of whatever TGA file you use as the bitmap is irrelevant.

Converting to Unreal Format: Preparation

You’ll need a copy of the 3ds2unr.exe conversion program, plus some way (Photoshop, Debabylizer, etc.) of converting TGA files to PCX format. A text editor (Notepad will do in a pinch) is also handy.

The conversion program expects an Unreal-like directory structure to exist before it will run. Specifically, you need:

  1. a main Unreal directory (mine is c:\Unreal), below which is a
  2. project-specific directory (for example, c:\Unreal\WOT), below which are
  3. two directories, Models and Classes (e.g. c:\Unreal\WOT\Models and c:\Unreal\WOT\Classes)

This directory tree is what Unreal itself expects, so it may already be set up. If it isn’t, you’ll have to make it yourself before doing any conversions.

The converter is a Windows console application, meaning it runs by typing rather than pointing and clicking. Make sure that the 3ds2unr.exe program is somewhere in your DOS path before you begin.

Using the Converter

Once you’re set up, using the converter is pretty simple. Just type 3ds2unr, followed by an optional class name and one or more .3DS files, like so:

3ds2unr Trolloc Walk.3ds Run.3ds Attack.3ds

The converter reads the given 3DS files, and produces a class file (Trolloc.uc) and model files (Trolloc_a.3d and Trolloc_d.3d) to be used by Unreal.

If this is the first time that you’ve run the converter, you’ll be prompted to select your project directory (i.e. the directory from item #2 in the preparation list (for me, c:\Unreal\WOT). Once you’ve set this directory, you won’t need to set it again. If you do need to change it, because you’ve began a new project, just type

3ds2unr –setproj

and you’ll be able to select another project directory.

When specifying 3DS files, you can use standard DOS wildcard characters (`?' and `*'). So, if all of those Trolloc animation sequences were the only 3DS files in the current directory, you could type:

3ds2unr Trolloc *.3ds

The class name is just the name of the object that you’re converting (Trolloc, AngrealHealing, Myrddraal, etc.) and is used as the base filename for the converter’s output. If you’re converting an object with no animation, you can omit the class name, in which case the base name of the sole 3DS file is used as the class name. In other words, this:

3ds2unr AngrealHeal.3ds

does what you probably want it to. However, if you try to convert more than one 3DS file at a time without supplying a class name, you'll be prompted to make sure that the class name inferred by the converter is correct. For example, omitting the "Trolloc" from the previous example is probably an error:

3ds2unr *.3ds
ClassName [Walk]?

You can just hit Enter to continue with that name, or type the correct name (Trolloc) first.

Be careful with your class names – the converter will happily overwrite existing files.

Converter Output

The converter will create three files:

    1. ...\Models\ClassName_a.3d
    2. ...\Models\ClassName_d.3d
    3. ...\Classes\ClassName.uc

(where "..." is your project directory).

The .uc file will contain the appropriate UnrealScript commands to import your model, list its animation sequences, and set its textures.

Unreal needs all three files to use your model. The same three files are used by the Mesh Viewer (see below, and separate documentation) to view models.

Fixing Texture Maps

Since the converter doesn’t read 3DS materials files, and Unreal requires PCX rather than TGA-format input, you have to manually help out the converter.

First, you need 8-bit PCX versions of all of the textures that you used in the model – use Photoshop, etc.

You then need to examine the .uc file in a text editor that can handle straight ASCII text – Notepad is fine. Look for the lines that begin with #exec TEXTURE IMPORT and note that each such line ends with a material name after a pair of slashes:

#exec TEXTURE IMPORT NAME=JSpider1 FILE=MODELS\Spider1.PCX GROUP=Skins FLAGS=2 // SpiderSkin

(The above should be a single line, but can’t be shown here legibly that way.)

Notice the reference to a Spider1.PCX file. Both Unreal and MeshViewer will need this file to properly display your model. It corresponds to whatever TGA file you used in the given material, SpiderSkin. You need to have this file name match the name of the material’s 8-bit PCX file, which you can do by either editing the .uc file directly, or renaming your PCX file to correspond with the name in the .uc file.

Using the above example, say that the SpiderSkin material was made with a SpiderSkin.TGA texture map. You’d convert that TGA file to and 8-bit SpiderSkin.PCX file. You could then either rename that file to Spider1.PCX (because that’s what the script is expecting), or edit the script to look for SpiderSkin.PCX instead of Spider1.PCX.

Conversion Errors and Warnings

You might encounter the following problems when converting:

can't find file

You referred to a file that doesn’t exist. Make sure you’ve typed the name and directory correctly.

No project directory found – exiting

The converter couldn’t establish a project directory, either because you cancelled out or there’s a problem in the system registry. Make sure that your project directory structure is correct, then try rerunning the converter with the –setproj option before attempting conversion again. The converter cannot run without a project directory.

read error [TAG]

The converter was expecting data that wasn’t there. This probably means the 3DS file is corrupted.

too many textures

Unreal has a limit of ten materials that can be applied to an object, and the converter encountered an eleventh material. For memory and rendering performance reasons, you really should be using less than ten anyway.

Warning: out of sequence obj (Foo) skipped

The converter expects to find sequentially numbered objects in file, and it found an object either without a sequence number (e.g. Box instead of Box01) or with an out-of-sequence number (e.g. Box01, Box02, Box04). This is probably something you want to fix, although in some cases, like leaving a stray light source in the project, it might be OK to ignore (providing that the correct object was converted).

Warning: Filename.3DS: Bad coordinate x.xxxxx, y.yyyyy, z.zzzzz

The converter found a coordinate that was outside the allowable 256x256x256 coordinate space. Rescale your model or fix the animation sequence. To minimize warning lines, only one bad coordinate is reported per object in the file.

If you encounter errors other than those listed here, it probably indicates a converter bug.


The Extended Brush Builders

The Extended Brush Builder Pack

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

These are some of the Epic brush builders that come with UnrealEd, with a few extra options. They are not 'Tarquin something' and come in a seperate pack, since I have only added a few lines of code to each script. If anyone else has modifications to the Epic builders, I'd be happy to include them in a future release and to consider this pack an open project.

ExtendedBrushBuilderPack100.umod (10 Kb): for hands-free installation.
 ExtendedBrushBuilderPack100.zip (10 Kb): follow the installation procedure in the included documentation.
I recommend you use this with UT patch 432 or higher. If you successfully use the pack with a lower version please let me know.

Installation

After installing the pack, the UnrealEd toolbox will gain two new buttons. These will function in exactly the same way as the native builders: left-click to build, right-click to open the parameters window.
The installation adds a new .u file to the /system folder, two .bmps to /system/editorres, and a single extra line to unrealtournament.ini. Nothing existing on your system is overwritten.

Features in release 100 (6 April 01):

Parallelepiped builder

Extends the cube builder with options to make slanted boxes — this was suggested by Carlos Santellanes. This boils down to adding variables to specify all 6 possible skew types. In an attempt to make them meaningful (rather than matrix elements), these are:
BaseSkewX, BaseSkewX: skew the base poly;
InclineX, InclineY: cause the vertical edges to lean;
DipX, DipY: skew in the z direction.

BaseSkewY and InclineY

DipX and InclineX, I've lined up the top of the brush to the outer box for clarity.

Wave builder

This is the terrain builder with a twist: the heights of the vertices that make a grid on the base are given by a sine wave.

WaveHeight

The half-height of the waves. They will extend by this amount above and below the base terrain brush's box. Beware: setting this to too large a number will cause BSP errors as the side diagonals will be crossing empty space.

PeriodX, PeriodY

The number of periods for the wave in each direction. Note this need not be a whole number — set to .5 for a single hill for example.

PhaseX, PhaseY

Shifts the wave across in the X or Y direction by this number of units.

MergeCoplanars

Set this to true to reduce the number of polys in the brush. This uses UnrealEd's built-in coplanar merge option; it's better to use this rather than a polys>merge command on the built brush, as this removes spare edges from the brush too. If you use this option, I do not recommend editing vertices on the resulting brush!

Future Development

I may change the Wave Builder so there is no danger of bad side polys. This would essentially be a complete re-write from scratch, and as such I'd move it from this pack to the Tarquin pack. (and p-shop the icon's HSB to that lovely shade of purple!)

Legal stuff

The scripts in this pack are based on code that is (c)1999 Epic Megagames, Inc. The bitmap icons and the modifications to these scripts are (c) Tarquin 2001 (tarquindarkling@bigfoot.com)
In the interests of keeping versions of this pack in one place, you MAY re-use or alter this code provided that you notify me and agree to changes being incorporated into future versions of this pack.
You are NOT allowed to commercially exploit this release, i.e. put it on a CD or any other electronic medium that is sold for money without my explicit permission.
You MAY distribute this release through any electronic network (internet, FIDO, local BBS etc.), provided you include this file and leave the archive intact.
UNREAL TOURNAMENT (c)1999 Epic Megagames, Inc. All Rights Reserved. Distributed by GT Software, Inc. under license. UNREAL TOURNAMENT and the UNREAL TOURNAMENT logo are registered trademarks of Epic Megagames, Inc.
All other trademarks and trade names are properties of their respective owners.

Disclaimer

This pack is provided 'as is'. I have tested the builders, and believe them to be free from errors. However, as you may know, BSP errors can occur in a level built from only the native brush builders. By installing and using this pack you agree that I will not be liable for any damage to your data resulting from use, direct or indirect, of this pack.


Tarquin's Extruder Tutorial: part 1

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

Part 1: the path

When I posted to the PU forum suggesting a gallery page of cool brushes made with the extruder, several people responded that they hadn't yet figured it out. With that in mind, here's something that may help. I only hope the title of part 1 doesn't make it show up in search engines as a religious cult ;)

Preliminaries
Use the latest build of the extruder (currently 080).
Make sure your red builder brush is reset.
Unreal uses a left-handed co-ordinate system — this means that the y-axis goes in the opposite direction to the way you may remember from school or college.

Terminology
A brush made with the extruder tool is basically a long tube, that bends to follow a path.
Essentially, we are making a multi-story box, which will be allowed to bend so each story's 'up' may be in a new direction. (wouldn't you like to work in an office like that?)
The shape is the original floor-plan of the building — the blueprint. The joints of the brush are the actual floor levels of the building. The sections of the brush are the stories of the building — the walls that join two floors together.

Now, if you were to make a picture frame out of wood, you'd take 4 pieces of wood and mitre the corners. If the pieces of wood had a square cross-section, the cut made to meet at the corners would show a face which would be a rectangle — the square shape has been stretched because the cut doesn't cross the piece of wood at a right angle.
In the same way, our office-building floor plan may be stretched at the joints. Using the _ShowJoints command will make just the floor plans out of sheets (more on the command module later). I doubt you'd ever want to actually use a brush that's just the floor plans, but building this simplified version can help you see how the shape is being made.
So 4 points, for example, will make a 3-storey brush, with 4 floor plans: the last story needs a roof as well as a floor.

Going back to our wooden version, you'd use several sections of wood, which you'd join together. With this in mind, I refer to the brush as being made from sections, which meet at joints. The vertices of the brush are all at the joints, and the polys join them up to make the sections.
The path is a list of vectors that define points in 3D space. Join these up to make a line with bends in. Now the points indicate where the joints should go, and the lines between them show the direction of the sections.
Unless the brush is made into a complete loop, the brush will also have two caps, in the same way a cylinder brush does. These correspond to the ground floor and the roof of our building.

Example 1.0: The Shape

The shape should be described in the XY plane. Build 075 gives preset shapes, so we'll use those for now and deal with making other shapes later, so you don't need to type in any shape vectors. The square preset is the simplest, so we'll start with that:
Make sure you've selected ShapeSource=SO_pSquare and that all the values in the PresetMetrics are left at zero. This tells the preset to make a square of the default size: side length 1, with a corner at the origin and the opposite corner at the point x=1, y=1.

Here's the default preset square, shown in the XY plane. We're not building anything yet, this is just to show you what it looks like before we make anything out of it.

Above & top: 3-D view.
Right: front elevation, ie the XZ plane.
The y-axis comes out of the screen towards you and the square is seen side-on.

Example 1.1

Since the shape starts off in the XY plane, it's best at first to send the path travelling upwards.
Set MergeCoplanars to false, otherwise the BSP merging will fuse the sides and leave you with a tall box such as you'd make with the cube builder.
We're going to set 4 points, which will make a box with 3 storeys (3 not 4 because the sections go from point to point, so each point starts a section except for the last point which closes the last section).

The ShapeFactor and PathFactor values allow vectors to be entered as multiples of the grid size. For example, the path point (0,1,2) with PathFactor=64 means the point will be scaled up to (0,64,128). This makes typing them in easier, as the numbers are smaller and you can count grid points to see where a point should be. Here I've used 64 for both, since it makes fairly chunky shapes that you don't have to zoom in on too much.
You should also check that PathSource is set to SO_Vect_Abs. This means that each vector will represent a path point measured absolutely: from the origin. Setting it to relative will take each vector as measured from the last point, which can be easier. More on this later.

Set the path points thus:
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 1 )
PathPoints[2] = ( 0 , 0 , 3 )
PathPoints[3] = ( 0 , 0 , 4 )

Above & top: 3-D view.
Right: front elevation, ie the XZ plane.
The y-axis comes out of the screen towards you.

As you can see from the front elevation picture, working out the path points is just a matter of counting the grid squares.

Example 1.2

Now we're going to allow it tip over at the joints. Type in these path points:
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 1 )
PathPoints[2] = ( 3 , 0 , 4 )
PathPoints[3] = ( 6 , 0 , 4 )

Above & top: 3-D view.
Right: front elevation, ie the XZ plane.
The y-axis comes out of the screen towards you.

The path now goes up, then diagonally, then along parallel to the x-axis. The brush keeps the same cross-section throughout — the shape has been tilted at each joint to follow the next piece of the path.
In case you're wondering, the diagonal line in the last section is a glitch: that side poly is split into two triangles. It's fixed in build 078. (It's not dangerous, and poly merging the built brush may merge them into one. I think it's caused by the floating point values being rounded off. Blame C++ for dealing with floating point decimals instead of proper irrational numbers.)

Conclusion

This is all I've had time to make for now, and also probably all that can hold on a single page before the images really slow down load times. I hope this will give an idea of what can be achieved with the Extruder.
I suggest that you take the last example, and add or change the path points and see what happens. Keep the path in the XZ plane for now, so you can easily visualize it in the front 2D view.
Try these:

This makes a bendy pillar:
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 1 )
PathPoints[2] = ( 3 , 0 , 4 )
PathPoints[3] = ( 3 , 0 , 8 )

This makes an arch:
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 1 )
PathPoints[2] = ( 3 , 0 , 4 )
PathPoints[3] = ( 6 , 0 , 4 )
PathPoints[4] = ( 9 , 0 , 1 )
PathPoints[5] = ( 9 , 0 , 0 )

This makes an even bendier pillar:
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 1 )
PathPoints[2] = ( 3 , 0 , 4 )
PathPoints[3] = ( 3 , 0 , 6 )
PathPoints[4] = ( 0 , 0 , 9 )
PathPoints[5] = ( 0 , 0 , 12 )

Suggestions and comments about this tutorial, and screenshots of things you've extruded for a gallery page are welcome: tarquin@planetunreal.com

© Tarquin 9 April 2001


Tarquin's Extruder Tutorial: part 2

The path in relative terms

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

Preliminaries
Use the latest build of the extruder (currently 080).
Make sure your red builder brush is reset.
Read part 1 of this tutorial!

Example 2.1

We'll start by making an archway, similar to the one I left as an exercise at the end of part 1.
Check your red builder brush is reset, and the grid size is 64. Make sure the ShapeSource property to pSquare, and both Factor properties are set to 64.
Enter the following path points and press build.
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 2 )
PathPoints[2] = ( 2 , 0 , 6 )
PathPoints[3] = ( 6 , 0 , 6 )
PathPoints[4] = ( 8 , 0 , 2 )
PathPoints[5] = ( 8 , 0 , 0 )

The diagram shows the front view. The path points are marked in yellow, starting at the origin and going up, across and back down to the x-axis.

Example 2.2

Now let's suppose we want to make our arch wider by 128 units. We could of course use vertex editing, but we're going to re-build our brush with different parameters.
We want points 3,4 and 5 of the path to move to the right — in other words, we want the x co-ordinate of those points to increase. Because we're working with PathFactor set to 64, all the vectors we're entering into PathPoints get multiplied up by 64. So 128 units is 2 x 64, which means we want the right-hand side of the arch to move by two grid squares, so we want to add 2 to the x co-ordinate of the vectors for points 3,4 and 5.
However, we're not going to do this, because there's an easier way.

Relative Paths
So far, each vector we've entered has represented a point measured from the origin. Another way of putting it is that each time we're counting from the origin, giving instructions like this:

Point zero is at the origin.
Point 1 is 2 North from the origin.
Now go to the spot that is 6 North and 2 East of the origin... etc

There's another way of doing this. Think of treasure maps. The best ones usually say something like:

Start at the origin (okay, so the pirates were mathematicians!)
Go 2 North.
Now go 4 North and 2 East... etc

This type of instruction tells you how far to go on from where you currently are.
So the path for the arch we've built in the previous example could be written in relative vectors like this (don't type these in!):
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 2 )
PathPoints[2] = ( 2 , 0 , 4 )
PathPoints[3] = ( 4 , 0 , 0 )
PathPoints[4] = ( 2 , 0 , -4 )
PathPoints[5] = ( 0 , 0 , -2 )

This says: start at the origin. Go up, go up & across, go across, go down & across, go down. When looking at the grid and trying to work out what to type in for points, this format is easier because there's less counting involved.
To make this arch wider all we would need to do is change the number 4 in PathPoints[3] — that says 'go across' — to a larger number.
We're not going to type in all the path points all over again in the new relative form though! This would be terribly tedious, and so we're going to let the Extruder convert them for us...

The Command Module
Scroll down the list of properties until you find _COMMAND. This property lets you give special commands to the builder.
Set this to C_ConvPath: this command converts the vectors in the PathPoints list from absolute to relative and vice-versa, and completely bypasses the building process. Check that PathSource is still set to Vect_Abs — the command module looks here to find out which format you are currently using.
Press build. The following things will happen, though note that the properties window doesn't redraw itself until you make it active.

  • The red builder brush will not change

  • The vectors in the PathPoints list will change to look like the list given earlier in this example.

  • The PathSource property will change to Vect_Rel. This is as a convenience, so you don't need to remember to change it.

  • The _COMMAND property will reset itself to C_None — the command module is back to neutral and will not be called into action next time the build button is pressed.

Now find PathPoints[3] and change the x value to 6, then press build.

Note that as well as describing the point's position relative to the previous point, you can also think as the first vector as describing point zero, and then the other vectors describe the sections of the path.
From now on path points will be given as relative vectors, unless stated otherwise.
I'll return to the command module in a later part of this tutorial.

Example 2.3

We're still not happy with this arch. We want to change the sloped bits.
Change the following:
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 2 )
PathPoints[2] = ( 2 , 0 , 2 )
PathPoints[3] = ( 4 , 0 , 0 )
PathPoints[4] = ( 2 , 0 , -2 )
PathPoints[5] = ( 0 , 0 , -2 )

Note that with build 078 or later, you won't get the glitchy diagonal line that you can see in this screenshot in the horizontal section of the arch. These pics were made with an earlier build and I really can't be bothered to do them again.

Example 2.4

...except now it's too short! To make it taller, we change the first and last sections. Those are given by points number 1 and 5:
PathPoints[0] = ( 0 , 0 , 0 )
PathPoints[1] = ( 0 , 0 , 4 )
PathPoints[2] = ( 2 , 0 , 2 )
PathPoints[3] = ( 4 , 0 , 0 )
PathPoints[4] = ( 2 , 0 , -2 )
PathPoints[5] = ( 0 , 0 , -4 )

Conclusion

Like bad television, we end with all the characters having a jolly jape.
Like bad kids' television, we clumsily fit in something educational or moral.
The list of path points in the Extruder properties can represent an absolute path or a relative path. The Extruder doesn't know on its own which type you are using, you need to tell it by setting the PathSource property.
Absolute vectors are simple point vectors. Each tells you how to get from the origin to the point.
With a path described by relative vectors, the first vector gives the position of the first point from the origin. The 2nd vector tells you how to get to the 2nd point from where you curently are, and so on.

Suggestions and comments about this tutorial, and screenshots of things you've extruded for a gallery page are welcome: tarquin@planetunreal.com

© Tarquin 17 April 2001


Tarquin's Extruder Tutorial: part 3
Turning and tilting the path

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

Preliminaries
Use the latest build of the extruder (currently 080).
Make sure your red builder brush is reset.
Read parts 1 and 2 of this tutorial!

Example 3.1

You may have noticed that all the paths we've tried so far have several things in common:

  1. The first point has always been zero: the path has remained anchored to the origin.

  2. The second point has always been of the form (0,0,a): the path has always started out by going straight up.

  3. The y co-ordinate of all path points has always been zero: all paths so far have been restricted to the XZ plane.

We'll start by letting the path bend into the y direction.
These are absolute path points; so make sure the PathSource property is set to Vect_Abs.

PathPoints[0]=(0,0,0)
PathPoints[1]=(0,0,2)
PathPoints[2]=(2,0,2)
PathPoints[3]=(2,2,2)

The brush with the path points marked out in yellow.
The path starts at the origin, then goes up the z axis, then along parallel to the x axis, then turns again to run parallel to the y axis.

Just the path.

The brush again, but this time I've deleted edges that are behind to make it look solid. The path points are again picked out in yellow, except the first one at the origin which is hiding from you.
Notice how the middle section is mitred in different directions at either end.

Example 3.2

There's only so many times I'll bake up a tryptich like that in p-shop. The best way to get a feel of these brushes is to build them and do much mouse-waving in the camera view.
Try these points. I've listed them as relative so make sure the PathSource property is set to Vect_Rel. You can press build after entering each point to see how the brush grows section by section.

PathPoints[0]=(0,0,0)
PathPoints[1]=(0,0,2)
PathPoints[2]=(2,0,2)
PathPoints[3]=(0,0,2)
PathPoints[4]=(0,8,0)
PathPoints[5]=(0,0,-2)
PathPoints[6]=(-2,0,-2)
PathPoints[7]=(0,0,-2)

The shape starts on the left of the picture. You can see by looking at the path points that by the time it reaches the end of the path it's been turned through a full 180 degrees.

Example 3.3

We'll now take a look at a path that doesn't start by going straight up.
For the last example, we used 8 path points, and rather than go through them all typing lots of zeros, we can use the Command Module to reset the path for us: select C_ResetPath from the drop-down list in the _COMMAND property, then press build. All the values in the PathPoints list will be set to zero, and the _COMMAND property will be reset to neutral. Your red builder brush will not change — this command leaves the builder brush alone.

PathPoints[0]=(0,0,0)
PathPoints[1]=(1,0,2)

It doesn't matter what you set PathSource to — a path with only two points has the same vectors in either type (think of pirates!).

The base of the brush tilts over, so the base of the brush is always a true cross-section.
To return to the office building analogy, the floor-plan for the very first storey is always exactly the same as the blue print — it's just that here the architect's dogsbody didn't quite interpret survey data properly and the building is on rather a steep hillside.

Example 3.4

PathPoints[0]=(0,0,0)
PathPoints[1]=(2,0,2)

The building is now tilting at 45 degrees. Note that you can't get this brush by rotating the previous one: firstly, the distance between the two ends is greater, and secondly the brush from example 3.3 dips at an angle that isn't on UnrealEd's rotation grid.

Example 3.5

PathPoints[0]=(0,0,0)
PathPoints[1]=(2,0,1)

Tilting even further.

Example 3.6

PathPoints[0]=(0,0,0)
PathPoints[1]=(2,0,0)

The building is now tilted all the way to horizontal.
Now it gets a little tricky:
Follow the sequence of 4 pictures (making an animated gif of them seemed tacky), looking at the base shape in particular. In the first picture, where it's only tilted a little, the square base is seen from the side.
You can imagine the original shape, the blueprint, lying flat, starting at the origin and extending along the x-axis. It also extends along the y-axis out of the screen, though we have to imagine that.
The x-axis side of the base is gradually tilted, until in the last picture it's pointing downwards, along the negative z-axis. The y-axis side of the base hasn't changed, it still points out of the screen towards us.

It's helpful to imagine the original shape — the blueprint — having its own personal axes, x and y. In this example we've rotated the blueprint to make the base of the brush so its x-axis now points down the world's negative z-axis.
In the next part of the tutorial we'll start building with shapes other than the preset square, and the way in which the blueprint is turned will be important.

Suggestions and comments about this tutorial, and screenshots of things you've extruded for a gallery page are welcome: tarquin@planetunreal.com

© Tarquin 19 April 2001


Tarquin's UT mk2

Tarquin's Cylinder Builder

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

This makes a cylinder just like the native builder, but adds support for partial revolutions. People who remember the advertising campaign on UK telly in the 80s may, like me think it looks like a piece of Edam cheese, hence the Edam version of the icon above.

Options

Height

Height of the cylinder.

OuterRadius, InnerRadius

These are the same as the native builder.

Sides

Number of sides of the cylinder. Note that the Unreal engine splits polys with more than 16 sides.

SidesUsed

Works like the 2D editor's revolve tool, with an added extra: leaving this at zero signifies 'full circle', so the number of sides of a full cylinder can be specified without having to enter two values.

Hollow

Same as the native builder.

TriangulateCaps

If the cylinder isn't hollow, this will split the two caps into triangles.
Note: A partial cylinder that makes more than half a circle will have triangulated caps no matter what this is set to.

AlignType

Plain and Side work the same as the False and True values in the Epic cylinder builder's AlignToSide property respectively; Caps is a special case of Side which cuts the first section of a partial cylinder to the x-axis.
This shows the possible cases:

GroupName

Works the same as in the native brush builders.

Known issues

None.
 Contact me if you find any bugs.

Future development

Flexible metrics, minimal triangulation, silly height settings, sides settings. See the development page .


Tarquin's UT mk2

Panorama Builder

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

This builder makes a panorama: a set of sheets arranged to make an open cylinder. This is intended for building backdrops in the skybox: most of the Epic maps use a mountain backdrop with 4 sides and 2 sheets per side.
The panorama could also be used for building waterfalls like the ones in DM-UT-Tourney][ by Olav Gjerde, as seen on the 0wnage.

Options

Height

Height of the brush

.

Radius / PanelWidth

The radius of the panorama can be set either directly or by specifying how wide each panel should be, allowing skybox textures to be aligned correctly.
These two options are mutually exclusive — set whichever one you want to use, and set the one you want the builder to ignore to zero.

Sides

Number of sides of the cylinder formed by the sheets.

PanelsPerSide

Number of sheets on each side of the cylinder.

AlignToSide

Works like the 'align to side' option in the native builders.

GroupName

Works the same as in the native brush builders.

Known issues

None.
 Contact me if you find any bugs.

Future development

I've had a request for an option to build with the polys facing the outside. This will be included in the next release.


Tarquin's UT mk2

Tarquin's Spiral Stair Builder

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

This builder is intended to replace the default Spiral Stair builder as well as the curved stair builder. I felt this was necessary because brushes made with the default Spiral Stair builder can't be subtracted.
In writing this new script, I've also found that the sloped floor / ceiling options in the native builder can throw up a lot of errors in the log. I don't know enough about the way UEd handles these to know whether this is bad for a level's BSP, but this new builder addresses this problem anyway. It also allows some new combinations, for example a flat base with a sloped top.
I had hoped to find a way to make the installation of this pack disable the default spiral and curved builders, but I do not think this is possible. If anyone knows of a way, please let me know!

Options

This builder comes with a large number of options. (I count 18 distinct shapes, before even considering the number of steps.) Not all options are compatible: some will generate a "Bad Parameter" dialog box, with explanations.

StepHeight

The height difference from one step to the next — the height that a player climbs for each step.

StepThickness

The actual height of each step block.
This is usually greater than StepHeight; setting the two to the same value will make a staircase where the steps only touch at an edge.
If StepThickness is less than StepHeight, each step is totally separate from its neighbors.

StepWidth

Width of the steps.

InnerRadius

Distance from the center of curvature to the inner edge of the steps.

StepsPerCircle

AnglePerStep * StepsPerCircle = 360 degrees, if you prefer. I use this because I work in radians, and so do UnrealScript's trig functions. It would take you a long time to type in all the digits of pi. ;)

NumSteps

The number of steps in the staircase. This can be larger than StepsPerCircle in some cases only — if you try something that isn't possible, the 'Bad Parameters' dialog box will explain the problem.

AntiClockwise

Yes, I'm English. Counterclockwise if you prefer.

TopStyle

Select whether you want sloped top, or regular top with steps, or a flat top.
The flat option will make stairs like the CurvedStair builder, and will not allow more than a full circle.
Note that a full circle, flat base brush, as with CurvedStair builder, will meet itself and two polys will touch — the subtracted brush will have a sheet effect between the first and last steps.

BottomStyle

Same as above. Note in particular you can't have both set to flat — the code is complex enough without building cylinders too.
You can't have both set to slope if StepThickness isn't strictly greater than StepHeight, since the brush would then have zero thickness throughout.
The builder checks for these and other problems and explains them as you go.

GroupName

Works the same as in the native brush builders.

Known issues

The textures on the walls are turned by 90 degrees. I plan to do... sod all about this, because this builder has been murder to write.
 Contact me if you find any bugs.

Future development

Several new features are on the way.


Tarquin's UT mk2

Torus Builder

By: Tarquin

tarquin@planetunreal.com

Tarquin's UT

This makes a torus, or sections of a torus, and was suggested by purice at the PlanetUnreal Forums.

Options

OuterRadius

The outer radius.

TubeThickness

It might have been more logical to call the radii OverallRadius and CrossSectionRadius, as suggested on PlanetUnreal forums, but I'd already written the code, picturing the torus as a bicycle tyre, made from an inner tube looped to meet itself. This is then the diameter of the tubing, and will also be the height of the torus. OuterRadius - TubeThickness = radius of hole in the middle.
Note for mathematicians, topologists and freaks on my wavelength: fiddle with the way it meets itself and you get a Klein bottle!

WheelSides

This is how many times the tubing is bent to make the full loop.

WheelSidesUsed

Works like the 2D editor's revolve tool, with an added extra: leaving this at zero tells the builder to use the value of WheelSides, so the number of sides of a full torus can be specified without having to enter two values.

TubeSides

The tubing is made from a cylinder with this number of sides.

WheelAlignType

'Plain' and 'Side' work the same as the AlignToSide 'False' and 'True' respectively; 'Caps' is a special case of 'Side' which cuts the first section of a partial torus to the x-axis.
This shows the possible cases, applied to the cylinder builder:

TubeAlignToSide

This works the same as the 'align to side' option in the native builders, and changes the alignment of the tube cross-section polygon. (To get a clear picture of what it does, set WheelSides to 4, TubeSides to 8, and look at both types in a side view.)

GroupName

Works the same as in the native brush builders.

Known issues

I've found that setting sides higher than 16*16 causes some of the polys not to display. This may be due to the sheer number of polys and BSP cuts.
Personally, I worry that because the vertices have irrational co-ordinates, what drops off when the floating point variable is rounded sooner or later becomes significant enough to cause a glitch — but I don't know enough about how these are handled internally.
 Contact me if you find any bugs.

Future development

I'd like to implement Item Naming options, so selecting polys by matching item gives either sections of tubing, or horizontal bands all the way round. More details on the future versions page .

Notes

See main page for legal stuff & disclaimer.


Welcome to MeshMaker

Welcome to MeshMaker General Information and Tutorial

By: Mychaeel

mychaeel@planetunreal.com.

MeshMaker Homepage
Step 1

What is MeshMaker?

MeshMaker is a Windows-based Unreal and Unreal Tournament editing tool that makes converting UnrealEd brushes (or, more precisely, prefabs) to decoration actors a matter of seconds.

Why Meshes?

Meshes (or, for our intents and purposes, decoration actors) have some advantages over brushes where it comes to detail work:

  • First and foremost, the engine can render much more raw mesh faces than brush polys. For comparison, an average player model (which is a mesh) has about 600 to 1200 faces, and the engine has no problems rendering scenes with many players in close view. That means that meshes can be much more detailed than anything you could create from regular detail brushes without a noticable slowdown.
  • Because meshes aren't part of the BSP tree, they never cause BSP holes or hall-of-mirror effects. When designing a prefab that's supposed to be converted to a mesh, you don't have to bother with grid alignment; same applies for placing meshes in your map.
  • The engine uses vertex lighting on meshes (as opposed to lightmaps on brushes). That's not necessarily an advantage since lightmaps are much more sophisticated than vertex lighting, but vertex lighting makes meshes appear smoother than brushes. Try that with a sphere, for instance.
  • Decoration actors are much more versatile when it comes to interactivity in maps: With just a simple property change, you can make them pushable, floating on water, destructible, revolving and more.

But it's not all sunshine, of course. The advantages mentioned above come at a cost:

  • Although meshes are rendered vastly faster than brushes, part of that advantage is sacrificed to the fact that meshes are always rendered as a whole when they're visible (as opposed to brushes whose individual surfaces are only rendered when they're in view). In virtually all cases it's still a big performance gain, though.
  • Meshes only support an upright collision cylinder, while brushes have per-poly collision.
  • The vertex lighting mentioned above is much less sophisticated than lightmaps. On the other hand, the difference is most obvious on large-scale objects which aren't suited for mesh conversion anyway, and occasionally the smoother vertex lighting even is a desired effect.
  • Not more than eight individual textures are supported per mesh, and textures can't be tiled on mesh faces as they can on brush surfaces. (MeshMaker automatically adjusts texture alignment to work around that limitation.)

Conversion Details

The converted prefabs retain their original size and orientation. Same applies to most static surface properties: Translucent, modulated, masked, unlit, two-sided, and non-smoothed. Mirror surfaces aren't supported by meshes, but MeshMaker converts mirror surfaces to environment-mapped mesh faces; it's a nifty effect, try it out.

You can always re-texture your converted mesh (or individual copies of it) by modifying the MultiSkins texture array in the Display section of the decoration actor's properties.

If you wish to embed the converted meshes in MyLevel in order to avoid to have to bundle an .u file with your map distribution, just type the following at the UnrealEd console before you add anything from that package to your map:

obj load file=SomePackage.u package=MyLevel

Common Pitfalls and Limitations

  • Prefabs must be completely textured. Prefabs with untextured surfaces can't be converted.
  • Meshes don't support more than eight individual textures (per mesh). Prefabs using more than eight textures can't be converted.
  • Textures can't be tiled on mesh faces. MeshMaker will automatically adjust texture alignment to the closest possible representation of the original prefab's texturing.
  • Unreal's software rendering mode has major problems displaying meshes; if your converted prefabs appear distorted in UnrealEd, don't worry and jump into the game to actually judge their looks. If the decorations seem to be strangely greenish, unselect them.

If something doesn't work for you that should work for you, it might be a bug. If you find a bug or some strange behavior that you suspect to be a bug, send me an email at mychaeel@planetunreal.com. Please try to provide as much information as possible; bug reports to the effect of "it doesn't work and you suck" are worthless and will be discarded. In any case, enclose the original .t3d file and the .u file MeshMaker produced if you're reporting a conversion-related bug.

Same applies to suggestions. I'm open for any suggestions you might have; I can't promise that I'll implement every suggested feature, but I'll definitely consider it.

MeshMaker Tutorial:

This quick walkthrough assumes that you know how to make a prefab from a piece of level geometry. If you don't, follow the link.

Step 1. Click the [browse] Browse button and select the prefab you want to convert. Alternatively, you can drag-and-drop a prefab file from Explorer onto the MeshMaker window, or you can simply enter the file name.

After you have selected the prefab file, MeshMaker will search all texture packages for the textures used by the prefab. This step is necessary because MeshMaker needs to know the size and package names of the textures used.

Step 2. MeshMaker lists the names of the textures used by the prefab and the packages that contain them. A green check mark [check mark] shows up next to each texture MeshMaker was able to find, and a red cross [red cross] is displayed next to textures that couldn't be found in any of the texture packages.

  • If all lines show a green check mark, [check mark] you're fine, and the Next button is enabled. Click it to proceed to the next step.
  • If one of the lines shows a red cross, [red cross] you have to manually find the texture in question; click on the line and select Browse from the popup menu. The Next button won't be enabled until all texture/package mappings are resolved.

The Status column in the texture listing displays in how many of the searched packages this texture was found. Normally, only a single package contains a given texture, so the Status column just shows "found." If, on the other hand, multiple packages contain a texture with the given name, MeshMaker picks the first one and shows "multiple" in the Status column; click on the texture or package name to preview all matching textures and to select the correct one.

Step 3. In the Class field, specify an arbitary name (composed of letters, numbers and underscores; no blanks!) for the decoration actor MeshMaker will create, and enter the name of the package that will contain the new decoration in the Package field. Warning: If you specify an existing package, it will be silently overwritten. Check Generate collision hull to make the decoration solid.

Step 4. Select an option:

  • The default setting of these radio buttons, Create a ready-to-use decoration, is usually fine. If you don't know what the other option means, leave the default setting and go ahead.
  • If you're an advanced user and wish to add code to the decoration subclass MeshMaker is about to create, or if you wish to manually edit the exported mesh, click Export the prefab as a model instead.

MeshMaker exports the model anyway, regardless of whether you select one or the other option. The difference between the two just is that MeshMaker automatically compiles the package if you select Create a ready-to-use decoration.

Step 5. Click Next to proceed. If you selected Create a ready-to-use decoration, MeshMaker will display a dialog box showing the progress of the compilation process; it usually takes just a couple of seconds to complete.
Step 3

Congrats, you're done!

You just created your first decoration with MeshMaker.

To use it in UnrealEd, open the Actor browser, and open the new package file that contains the decoration MeshMaker just compiled for you.

After loading the package, your new decoration is listed in the "Decoration" subtree. Simply select it, right-click into any of UnrealEd's viewports and use Add MyPrefab (or whatever name you gave it) to add it to the world.

MeshMaker HomePage

Download and Installation

MeshMaker is available for download as an automatic Umod installer and a simple Zip archive. Both versions contain the same files; they just differ in installation convenience.

FilePlanet | Umod installer | (502 kB) | Zip archive | (505 kB)
Link-M (Germany) | Umod installer |  | Zip archive

A note for webmasters: Please don't link to the individual downloads themselves; link to this page instead. The download locations might be changed or removed without prior notice.

Copyright and Acknowledgements

MeshMaker is © 2001 by Mychaeel mychaeel@planetunreal.com. Free for noncommercial use. For any other use and distribution, please contact me in advance. Thanks.

Kudos go to the following individuals and organizations: Antonio Cordero, whose excellent (and free) Delphi unit for Unreal package access saved me an insane amount of research and coding; David Townsend from Legend Entertainment for publishing the source code of the 3ds2unr tool, which provided me with vital information about Unreal's mesh format; Exodus-R from the BeyondUnreal Editing forums for publishing a thorough listing of possible face flags in Unreal meshes; Steve Tack for valuable information about Deus Ex's mesh format; and last but not least my beta testers, ElBundee and WillySurvive.

Oh, and really last but definitely not least the nice folks from BeyondUnreal's Editing forums that offered kind encouragement when I asked whether a tool like MeshMaker might be useful.


Untitled Document

Pillars

By: Expandable Jim

Meshes

If you have tried modeling anything complicated yet you will be aware of the most severe limitation of the Unreal engine. The recommended on-screen polygon count is two hundred or less. This is quite low when compared with other games. The best answer to this problem is meshes. Meshes are also used to display players, monsters, weapons, items and special effects. Their main advantage is that they are rendered much more efficiently than polygons in the level geometry. In fact they are handled roughly five times faster.

There are downsides though. Meshes do not handle collision properly. You can give them a cylindrical collision cylinder but objects will collide with the cylinder, not the mesh itself. Meshes are lit by simple vertex lighting, not the more sophisticated lightmap method used for level geometry. This means they cannot have shadows on them but on the positive side they are much more natural when they model curves. If you make a cylinder or cone with brushes you might get something like these pillars:

The lighting system makes it very clear that those pillars are made from flat polygons. This is not the desired effect. Now let us look at meshes:

They could have been better lit, but they do look much rounder thanks to the different lighting system. Both sets of pillars are essentially the same model, but the meshes look nicer.

Getting your feet wet

The easiest way to start is to try out the decorations in the actor browser:

There are many decorations to choose from. Be sure to expand the ut_Decoration subtree, since half of the decorations are in there. For now, we will use the Barrel.

Right click on the ground where you want to put it and click Add Barrel Here.

Voila! a barrel. It is a little out of place, but it is there nonetheless and appears in the game.

Of course there are more decorations than those found with the game. Many fancy decorations can be found on the internet. Decorations are distributed in .u files. Put these files in your UnrealTournament\system folder. If someone else wants to play a map that uses such decorations, they too will need the .u file in their system folder.

To use these custom decorations, you just need to put them in your system directory and open them from the actor browser. Then hunt around for them in the actor browser. (they will normally be under decoration)

The good bit

By now you are probably wondering how you can make such decorations yourself. After all, there are many fancy things you want to include in your map that you cannot get elsewhere.

The answer is a third party utility called Meshmaker. This is possibly the best third party utility you can download (there would be heated debate over this, but Meshmaker would be a strong contender). It allows you to convert a .t3d file into a .u file. That is, you can make what you need in UnrealEd, export the brush and convert it into a mesh.

here it is

There is a straightforward tutorial, included with meshmaker, on how to do this.

The complexities

Meshmaker creates a folder within your game folder with the code and model(s) needed to generate the .u file. If you selected 'create a ready-to-use decoration', it will compile a .u file from that code. If you make many decorations with the same package name all the code will go in one folder, resulting in a .u file that has not one but many decorations. But if you delete that folder and make another decoration with that package name, the resulting .u file will only contain the decoration you just made. Think before deleting those folders.

If you create anything large you may notice strange disappearances like this:

Here we see a large 512 unit high pillar vanish when we look down. This seems to happen when you look away from the centre of the decoration. I am aware of no clever property changes or things like that which fix this. Therefore, avoid using really large decorations. The robot decoration in the actor browser is just under 256 units high and shows this problem, but only if you go right up to it and look straight down.

It is possible to circumvent this problem by making the decoration in parts. This is effective though laborious and may increase the number of polygons in the mesh(es). In the case of a pillar you could extend it some distance downwards through the floor. This would move the center of the decoration down towards eye level and make disappearances less likely. Just be aware that it might make disappearances more likely on high up platforms.

Changing the Advanced->EdShouldSnap property of a decoration to True will make it snap to the grid the way brushes do. This is helpful if you are trying to put pieces together and generally just helpful.

Changing the Advanced->bStatic property to False and the Decoration->bPushable property to True will make it possible to push the decoration around. The size of an object does not make it harder to push.

If the decoration must be solid and that cylinder shape doesn't quite work you need to use an invisible collision hull. The problem with this is that it tends to make the decoration turn black. This is a lighting problem. The solution is to use several invisible collision hulls, avoid the center of the decoration and leave gaps. You can also use blockall actors, which do not make your decoration go black.

A series of invisible collision hulls. A single solid invisible collision hull would make that boiler go black. Another copy is in the background.

It is possible to use movers to create fake shadows. This is handy when used in conjunction with decorations, which do not leave shadows even though they often should. Place a mover. Put keyframe 0 where no-one will see it(it can sit in solid space) and keyframe 1 in the right place for casting a shadow. Make sure the Mover->bDynamiclight property is False, Mover->WorldRetraceKey is 1 and Mover->Keynum is 0. Also make sure that nothing can trigger the mover.


Camera Spot

by Mychaeel

mychaeel@planetunreal.com.

Camera Spot Homepage

[CameraSpot logo, left] [CameraSpot logo, right]

What is CameraSpot?

Remember Duke Nukem's surveillance cameras? When you approached and activated them, they showed you another part of the map from a surveillance camera's point of view, allowing you to check whether some door was open or closed, where enemies were hiding or where a special item was located.

The CameraSpot actor does the same for Unreal Tournament maps, and more. When triggered, the instigator's viewpoint switches to the CameraSpot; as soon as the instigator leaves the trigger's radius, his/her viewpoint is switched back to first-person view.

CameraSpots can be easily set up to monitor a fixed spot or to rotate slowly back and forth in order to cover a larger area; or attach them to a mover to create flyby sequences. CameraSpots can display an unzoomed view or zoom in as closely as you wish. In addition, you can set a short descriptive caption that is displayed at the bottom of the viewer's screen when watching through a CameraSpot.

Download

Includes DM-CameraSpot (which in turn includes the CameraSpot actor) and full documentation.

FilePlanet | Zip archive | (299 kB)
Link-M (Germany) | Zip archive

DM-CameraSpot

The code for CameraSpot is embedded in DM-CameraSpot. Loading DM-CameraSpot in UnrealEd will make the CameraSpot actor available in the actor browser (under Keypoint) until you close UnrealEd, even if you load your own map afterwards. If you add a CameraSpot to your map, the editor will automatically embed its code in MyLevel of your map. (Tip: Save your map, close UnrealEd and re-open it after adding the CameraSpot actor.)

The rounded edges and the white corners in those screenshots are just the default setting. You can change them to whatever you wish (or remove them altogether) if you don't like them or if they don't fit your map's theme. See below for details.

Demo map courtesy of Snowdog.

Tower (Static CameraSpot)
Tower (Static CameraSpot)

Overview (Rotating CameraSpot)
Overview (Rotating CameraSpot)

Flyby (Attached CameraSpot)
Flyby (Attached CameraSpot)

[CameraSpot properties, left]

Frequently Asked Questions

How do I get those rounded edges and corners from the screenshots and the demo?

    Import the .pcx files that are included in CameraSpot.zip into your map's MyLevel package. (If you don't know how to do that, here's a tutorial for it.)
    Then open your CameraSpot's properties and assign the textures you just imported to the matching CameraSpot properties: CameraSpotTranslucent00 to OverlayTexturesTranslucent[0], and so on.
    Click the [+] icon next to the OverlayTexturesTranslucent and OverlayTexturesModulated properties to view and modify their individual array elements.

I want to create my own monitor frame and use it with CameraSpot. Do I really have to fill all twelve elements of those OverlayTextures properties?

    No. If you specify less than twelve textures for either of those properties, they will be stretched appropriately (and if you specify just a single texture, it is even stretched smoothly). The following chart shows how the individual textures will be arranged on the screen (red outlines represent the textures, the gray outline is the player's screen):

    The dotted parts of the textures are outside the visible area. That's not a technical necessity, but it's usually more convenient (and looks better) if the texture's aspect ratio is maintained when they are rendered on the screen.

What does "modulated" mean anyway?

    Modulation means that texture parts that have a lightness of fifty percent are transparent. White parts are displayed white, black parts black; basically, the farther a color is from the midpoint, the less transparent it appears.

I have a map that uses an older version of CameraSpot and I want to update it to the lastest CameraSpot version. How would I do that?

    Tricky, but possible. (It might be a good idea to create a backup copy of your map before you do that.)
    Basically, you'll have to copy all your CameraSpots, cut them from your map, save the map and then close UnrealEd in order to get rid of the old code. Then re-open UnrealEd, load up DM-CameraSpot (in order to get the new code into the editor), load up your map and repaste the CameraSpots back into your map before saving it.
    Step-by-step: Open your map, select all of your CameraSpots (using the "Select all CameraSpot" command in UnrealEd's right-click menu after you have selected one of the CameraSpots) and press Ctrl+X to cut them into the clipboard. Then, save your map, close and re-open UnrealEd, open the new DM-CameraSpot and then your map; then press Ctrl+V to paste your CameraSpots into your map. They're collectively shifted a bit away from their original position due to your pasting them, so leave them all selected and move all of them back together.

Copyright and Acknowledgements

CameraSpot is © 2002 by Mychaeel mychaeel@planetunreal.com. This component is freely available for noncommercial use and distribution through any electronic network, provided you include this documentation file. For any other use and distribution please contact me for permission.

Thanks to Snowdog for creating the cool demo map; and to him, ElBundee, tarquin and WillySurvive for beta testing and feedback.

On a personal note, I am aware that I'm hardly the first to implement something like that (hey Beppo!), and it's a rather simple piece of code. It is, however, a much requested item, and CameraSpot is the only implementation I know of that is network-safe (in other words, works on clients in network games just as well as in standalone games). Have fun, and imagine the possibilities.


The Screen Component

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

What are screens?

Scripted textures used to be good for two things: Display your ammo count on various weapons, and tell the currently leading player on a scrolling banner in Morpheus. But that just scratched the surface of the potential of scripted textures.

Screens provide a very general approach to including dynamic textures in maps: A scripted texture that is connected to a Screen actor can display any number of so-called slides which can in turn show anything ranging from simple formatted text to complex dynamic game-related information.

The Screen package includes slide classes that allow the display of basic HTML formatted text including graphics (that have to be supplied as textures); players' positions as small colored dots on a sketch of your map, opening a completely new level of game tactics; or the current top players, similar to the score board. Any number and type of slides can be connected to a slide show, each slide with a different entry and exit animation. Text slides can pull their content from an arbitary web site upon loading the map if desired.

In addition to slide shows that run automatically you can add triggers to your map that switch a particular screen (or multiple screens) to a specific slide when they're triggered.

The Screen component is freely available for noncommercial use and distribution. Please send questions, suggestions and bug reports to [image] Mychaeel. If you are using screens in a map release of yours, I'd also be happy if you sent me a mail.

Contents

  • Screen
  • ScreenSlide
  • ScreenSlideMap
  • ScreenSlidePage
  • ScreenSlidePageChat
  • ScreenSlidePageWeb
  • ScreenSlideRanking
  • ScreenTrigger

Screen

Actor >> Info >> ClientScriptedTexture >> Screen

Screen actors are the link between slides and scripted textures. Screen actors handle rendering requests from scripted textures, run slide shows and do all entry and exit animation calculations. For each scripted texture in your map (that is supposed to be a screen) you need exactly one Screen actor.

Properties

ScriptedTexture | Located under ClientScriptedTexture in the property sheet. Scripted texture that is used by this Screen actor to render its content. Obligatory.

Left
Top
Width
Height 		The offset and dimensions of the virtual screen space on the scripted texture (in texture pixels, not world coordinates); that's the rectangular area that the Screen actor considers the visible part of the scripted texture. These settings are used to determine slide positions on the texture. Note that the slide display is not clipped at the borders of the virtual screen space.

SlideCurrent | Slide that is displayed on the screen, or the first slide of a slide show.

ScreenBackground | Texture that is drawn on the scripted texture before rendering the slides on top of it. Stretched to completely fill the virtual screen space. Useful if you want to use a custom background image on your screen without creating a custom scripted texture.

ScreenForeground | Texture that is drawn on the scripted texture after rendering the slides. Can (and probably should) be masked. Stretched to completely fill the virtual screen space. Useful if you want to create irregularily shaped screens.

TileMaster | Used for tiled screens only. Points to the master Screen actor that takes care of all necessary calculations while this Screen actor acts as a slave and only displays its part of the tiled screen.

TileLeft
TileTop 		Used for tiled screens only. Left and top offset (in texture pixels, not world coordinates) of this slave Screen actor's tile on the virtual screen space.

Troubleshooting

If you don't see anything on your screen, make sure the ClientScriptedTexture property is set correctly, and play with the Top and Left properties; UnrealEd sometimes does strange things with texture alignment.

ScreenSlide

Actor >> Info >> ScreenSlide

ScreenSlide is the common base class for all slide actors. Properties of this class specify generic slide behaviour. This is an abstract class and cannot be instantiated.

Properties

SlideOverlay | Another slide that is drawn on top of this slide, aligned according to its respective AlignHorz and AlignVert settings. Useful for displaying different slide types on the same screen at the same time, and for emulating HTML frames. Ignored if set to None.

SlideNext | Next slide in a slide show. Ignored if set to None.

Time | Used in conjunction with SlideNext. Time (in seconds) that this slide is displayed in a slide show. Ignored if no SlideNext is specified. Note that entry and exit animations don't count into this time, and that slides only switch on completing their scrolling animations.

AlignHorz
AlignVert 		Horizontal and vertical alignment on the virtual screen space (see [image] Screen). For overlaid slides, alignment in respect to the immediately underlying slide.

ClientWidth
ClientHeight 		Width and height of the slide content (in texture pixels, not world coordinates). Some slides adjust one or both of those properties to values depending on the displayed content.

ClientPaddingLeft
ClientPaddingTop
ClientPaddingRight
ClientPaddingBottom 		Additional padding (in texture pixels, not world coordinates) that is applied to the respective edges of the slide, thus making it larger (or smaller if negative values are supplied).

Palette | Texture whose palette is used for rendering the slide content; if set to None, the scripted texture's palette is used. Note that all elements of a slide (and its overlaid slides) share a common palette, and that this palette is also used for fade-in and fade-out effects.

Background | Texture that is drawn on the background of the slide.

BackgroundScroll | Used in conjunction with Background. Specifies whether the background texture is scrolled and animated along with the slide content or drawn at the fixed target position of the slide.

BackgroundTile | Used in conjunction with Background. Specifies whether the background texture is tiled if it smaller than the slide's total client area or not.

EffectEntry
EffectExit 		Animation effects that are used on entry and exit of this slide in a slide show. Note that fade-in and fade-out effects only apply on textual parts of slides, not textures. This property is ignored in overlaid slides; all overlaid slides share the effects of the bottom-most slide.

EffectEntrySpeed
EffectExitSpeed 		Used in conjunction with EffectEntry and EffectExit. Speeds of entry and exit effects. For slide effects given in pixels per second; for fade effects given in percent per second.

BackgroundColor | Used in conjunction with fade effects. Color from which or to which text is faded in fade-in and fade-out effects. This setting does not change the slide's background color; use an appropriate Palette or Background texture for that.

ScrollHorz
ScrollVert 		Horizontal and vertical scrolling animation that is used if the slide is larger than the virtual screen area. All overlaid slides share the bottom-most slide's scrolling animation.

ScrollHorzSpeed
ScrollVertSpeed 		Used in conjunction with ScrollHorz and ScrollVert. Speeds of horizontal and vertical scrolling animations, given in pixels per second.

ScreenSlideMap

Actor >> Info >> ScreenSlide >> ScreenSlideMap

ScreenSlideMap slides display the players' positions as small colored icons on top of a (mapper-supplied) sketch of the map. The selection of players displayed can be restricted to an arbitary coordinate cuboid, by the players' teams, their (in)visibility status and the zone they are currently in.

Properties

See also [image] ScreenSlide properties.

Map | Texture that is displayed in the background of the slide, stretched to its ClientWidth and ClientHeight. Should contain some two-dimensional representation of your map.

MapLeft
MapTop
MapRight
MapBottom 		World coordinates of the points that are represented by the Map texture's upper-left and lower-right corners. Used to calculate the players' positions in respect to the Map texture.

CoordHorz
CoordVert
CoordDepth 		Specify how a player's coordinates are mapped to the display; in other words, specify which of the player's coordinate components is used on the horizontal and vertical axis of the slide display. The CoordDepth setting is used in conjunction with CoordDepthMin and CoordDepthMax.

CoordDepthMin
CoordDepthMax 		Used in conjunction with CoordDepth. Specifies a range within which a player must be located to be displayed on the slide. If both CoordDepthMin and CoordDepthMax are set to the same value, this setting is ignored.

PlayerDisplay Text that is displayed next to each player's icon on the slide. The following macros are expanded:

%p | Player name
%h | Current number of hitpoints
%s | Current score

PlayerDisplayAlignHorz
PlayerDisplayAlignVert 		Horizontal and vertical alignment of the text that is displayed next to each icon. The left/right and top/bottom settings automatically wrap the text to the other side if it wouldn't entirely fit on the slide otherwise.

[121] PlayerDisplayPaddingTop
[121] PlayerDisplayPaddingLeft
[121] PlayerDisplayPaddingRight
[121] PlayerDisplayPaddingBottom 		Used in conjunction with PlayerDisplay. Padding around the text that is displayed next to each icon (in texture pixels, not world coordinates). These settings determine the distance between the icon and the text.

FontPlayers
FontPlayersColor 		Used in conjunction with PlayerDisplay. Font and font color used for drawing the PlayerDisplay text on the slide.

PlayerIcons | Texture that contains the icons displayed on the screen for each player. This texture contains all icons in each team color and for both visibility states in two rows (first row: visible players, second row: invisible players) with five columns each (from left to right: no/neutral, red, blue, green, gold team). Masked textures are supported.

PlayerIconsWidth
PlayerIconsHeight 		Used in conjunction with PlayerIcons. Individual width and height of the icons in the PlayerIcons texture.

[121] ShowDead | Specifies whether dead players are displayed on the slide until they respawn.

ShowNeutral
ShowRed
ShowBlue
ShowGreen
ShowGold 		Specify which teams are displayed on the slide.

ShowNeutralInvisible
ShowRedInvisible
ShowBlueInvisible
ShowGreenInvisible
ShowGoldInvisible 		Specify whether invisible players (players carrying the invisibility pickup) of the respective teams are displayed using their invisibility icon or not at all. Note that invisible players are only shown at all if their visible team mates are shown too.

ZoneDisplay | Specifies whether players inside or outside the given Zone or ZoneClass are displayed.

Zone
ZoneClass 		Used in conjunction with ZoneDisplay. Zone or zone class inside or outside which a player must be located to be displayed on the slide. If either of these properties is set to None, it is ignored. You can set both of them at the same time, but that's pointless; use the Zone property if you want to refer to a particular instance of a zone and the ZoneClass property if you want to refer to a whole class of zones (like all water zones).

ScreenSlidePage

Actor >> Info >> ScreenSlide >> ScreenSlidePage

ScreenSlidePage slides render basic HTML formatted text and graphics.

Properties

See also [image] ScreenSlide properties.

Text

Text that is wrapped to the ClientWidth of this slide, with optional HTML markup. The slide's ClientHeight is automatically set to accommodate the wrapped text's total height. The following HTML tags are supported (and all other tags are silently ignored):

<body text=> | Sets default color for normal text
<h1 align=> | Heading with optional text alignment
<p align=> | Paragraph with optional text alignment
<br> | Inserts a linebreak
<img src= width= height=> | Inserts a texture, optionally scaled to the given width and height
<font color= size=> | Sets font color and font size
<big> | Sets big font size
<small> | Sets small font size
<b> | Sets boldfaced font
<u> | Sets underlined font

Textures included with <img> must be specified including their package name if they are not located in the MyLevel package. Textures are automatically searched in MyLevel if they aren't found in their specified package.

[121] You can specify that only part of a texture referenced in an <img> tag should be used by appending ?w,h,l,t to the texture name, like MyLevel.SomeTex?4,1,12,53, where w and h are width and height and l and t are the left and top offset of the texture part to be used. You can omit any or all of those parameters.

TextCaps | Specifies whether the text is converted to capital letters before being rendered. Useful in conjunction with fonts that don't provide lowercase letters.

[121] TextPlaceholders

If set to true, the following placeholders in Text are replaced by live game data (anywhere, including inside tags):

Local player | Leading player |
%p | %lp | Player name
%s | %ls | Current score
%d | %ld | Number of deaths
%t | %lt | Playing time (in minutes)
%c | %lc | Team color (red, blue, green, yellow or gray)
%i | %li | Player icon

FontNormalColor | Default color for all text.

FontNormal
FontNormalBold
FontBig
FontBigBold
FontHeading 		Fonts that are used for normal and boldfaced normal text, big and boldfaced big text, and for headings.

ScreenSlidePageWeb

Actor >> Info >> ScreenSlide >> ScreenSlidePage >> ScreenSlidePageWeb

ScreenSlidepageWeb slides extend ScreenSlidePage slides by the capability to fetch their content directly from an arbitary web server on game start.

Properties

See also [image] ScreenSlide and [image] ScreenSlidePage properties.

Text | Located under ScreenSlidePage in the property sheet. Text that is displayed before content is fetched from a web server or from the cache.

AddressHost
AddressPort
AddressPath 		Host, port and local path of the URL from which the live content is fetched. For example, given the address http://www.planetunreal.com/screennews.html, the host is www.planetunreal.com, the port is not given and thus defaults to 80 (as in almost every practical case), and the local path is /screennews.html (including the leading slash and, if pointing to a directory, a trailing slash).

NetworkGameOnly | Specifies whether the slide attempts to fetch data from the specified online location in any case or in network games only. Joining a game on an online game server or running a listen server is considered a network game while playing in single player mode is not.

Cached | Specifies whether the content fetched from the specified web server is cached locally in order to be displayed as the default content next time the game is started even if NetworkGameOnly is set to false. This setting doesn't affect the attempt to fetch updated data from the web according to the NetworkGameOnly setting.

Remarks

The slide's content cache is stored in an ini file of your map's name in the UnrealTournament\System directory. If you want to deliver your map with a pre-filled cache, bundle this ini file with your map release. More convenient for your map's users however is a customized Text property setting.

[121] Triggering ScreenSlidePageWeb actors reloads their web content.

ScreenSlidePageChat

Actor >> Info >> ScreenSlide >> ScreenSlidePage >> ScreenSlidePageChat

ScreenSlidepageChat slides extend ScreenSlidePage slides by the capability to monitor an arbitary IRC channel and let the user participate in the chat. Everything a player Says while standing in front of a screen currently displaying a ScreenSlidePageChat slide will be sent to the channel.

Properties

See also [image] ScreenSlide and [image] ScreenSlidePage properties.

Text | Located under ScreenSlidePage in the property sheet. Text that is displayed before the connection to the server is established.

AddressServer
AddressPort
AddressChannel 		Server and port to connect to, and the channel that will be monitored by this slide. You can create several ScreenSlidePageChat actors using the same server and port; they'll implicitely share one server connection rather than establishing a separate one for each slide.

NetworkGameOnly | Specifies whether the slide attempts to connect to the server in any case or in network games only. Joining a game on an online game server or running a listen server is considered a network game while playing in single player mode is not.

SendSay
SendSayTeam 		Specify which in-game messages are sent to the channel. Setting SendSay to true will send everything that is publicly said in the game to the channel, settings SendSayTeam to true extends this to TeamSay messages.

SendWatching | Restricts the sending of in-game messages to the chat channel to players that are actually looking at the slide (yeah, indeed) in that moment if set to true. Otherwise, everything that is said anywhere in the map will be sent to the channel.

MessageConnect
MessageError
MessageJoin
MessageLeave
MessageNickname
MessageReceiveAction
MessageReceivePrivate
MessageReceivePublic
MessageSendAction
MessageSendPrivate
MessageSendPublic

Customizable HTML formatted text that is appended to the slide content at the given events. If you want to change the default colors or formatting of the messages that appear on the screen, here's the place to do it. Most of these properties support one or more placeholders for event-specific information:

%e | Error code | Supported by MessageError which is issued when the attempt to join the channel failed (replaced by a three-digit error code that might help IRC operators to solve the problem).
%m | Message | Supported by all MessageSend and MessageReceive messages.
%n | Nickname | Supported by MessageConnect, MessageJoin, MessageLeave, MessageNickname (replaced by the new nickname), all MessageReceive and MessageSend messages (replaced by the sender's nickname).
%o | Old nickname | Supported by MessageNickname (replaced by the old nickname).

Remarks

In addition to just sending messages to the channel, players can Say the following commands to perform special IRC operations:

/me <action> | Lets the user say that he or she performs an action. Saying /me is asleep in a channel results in the message Mychaeel is asleep being sent to the channel (provided the user's nickname happens to be Mychaeel).
/msg <nickname> <message> | Sends a message to the given user privately; it won't appear publicly on the channel. Referred to as "whispering" sometimes.

The IRC client built into the ScreenSlidePageChat actor supports basic CTCP operations and is able to interpret color and formatting codes embedded in incoming messages; there is however no way to specify formatting codes in outgoing messages.

ScreenSlideRanking

Actor >> Info >> ScreenSlide >> ScreenSlideRanking

ScreenSlideRanking slides display the top few players on a slide next to their pictures (the ones that are displayed in the chat area), roughly similar to the score board.

Properties

See also [image] ScreenSlide properties.

EntryCount | Number of top ranked players that are displayed on the slide (provided so many players are currently available).

EntryHeight | Height of a single ranking entry (in texture pixels, not world coordinates). Also determines the size of the player picture that is displayed on the left of each entry.

EntryPadding | Padding between each two ranking entries (in texture pixels, not world coordinates).

[121] ShowNeutral
[121] ShowRed
[121] ShowBlue
[121] ShowGreen
[121] ShowGold 		Specify which teams are displayed on the slide.

Caption
Info 		Text that is displayed as the Caption (top) and the Info line (bottom) of each ranking entry. The following macros are expanded:

%p | Player name
%s | Current score
%d | Number of deaths
%t | Playing time (in minutes)

CaptionFont
InfoFont 		Fonts used for displaying the Caption and the Info text.

CaptionFontColor
InfoFontColor 		Colors used for displaying the Caption and the Info text.

CaptionColorTeam | Specifies whether the player's team color is used for drawing the Caption text rather than the color supplied in the CaptionColor property.

CaptionCaps
InfoCaps 		Specify whether the Caption and the Info text is converted to capital letters before being displayed. Useful in conjunction with fonts that don't provide lowercase letters.

ScreenTrigger

Actor >> Triggers >> ScreenTrigger

ScreenTrigger triggers provide a means to include interactivity to your slide show: When triggered, they switch one or more screens to a specific slide on all clients.

Properties

Tag | Located unter Events in the property sheet. Arbitary string that is used to identify this trigger for other triggers or dispatchers.
Event | Located unter Events in the property sheet. Arbitary string that identifies the Screen actors affected by this trigger. Set those Screen actors' Tag property to the same string as the Event property of the ScreenTrigger that should be connected to them.
SlideSwitch | Points to the slide to which the affected screens switch when this trigger is triggered.


Screen

Screen : Compatibility

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

compatibility

All versions of the Screen component are fully downward compatible to previous versions for both players and developers; for example, if you have Screen 121 installed you can connect to and play on a server running Screen 120 without problems.

However, if you have an earlier Screen version installed than the game server you want to connect to, there's a number of potential issues you can run into:

[compatibility warning message]

Screen 121 and later versions show a compatibility warning message when joining a game on a server that runs a newer Screen version than you.

* | If you are playing a map that doesn't use the Screen component, you won't notice a difference.
* | If you are playing a map that uses the Screen component, you may find that some known Screen features don't work anymore, or that some new features don't look as the mapper intended because they aren't supported by your local Screen version.
* | You might not be able to connect to the server at all if the map currently being played there contains Screen related actors that aren't yet included in your local Screen version.

Conclusion: Always install the latest available Screen version.

Side note: Screen 121 and later versions notify the user when the server is running a newer Screen version than the one installed on the client computer.


Screen

Screen : FAQ

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

frequently asked questions

If you're stumbling over obscure problems while implementing screens in your map and don't find the solution in the [image] docs, here's the first place to look for answers. And if you have any question or answer that you find might fit into this section, please don't hesitate and [image] let me know.

Why don't the Screen-related actors show up in UnrealEd?

You have to edit UnrealTournament.ini manually to make the Screen-related actors appear in UnrealEd unless you used the UMOD installer. See the [image] installation section for details.

How much bandwidth does a screen take?

That depends on which slides you use.

* | ScreenSlidePage and ScreenSlideRanking slides don't take any bandwidth at all.
* | ScreenSlidePageWeb slides have to download the document you specified once at game start. Every client does that on its own, so this takes just as much bandwidth as the document's size is.
* | ScreenSlideMap slides replicate every player's location and their visibility status from the server to the clients. That's approximately six to twelve bytes per second per player, depending on how often the locations on the slide are updated.

All in all screens have negligible bandwidth requirements; in addition, replication for screen slides has by default lower priority than game-relevant information.

What's that flickering at the bottom/right edges of my screen?

An Unreal bug. Pad the scripted texture a bit down, and it disappears.

What's that black row of pixels on the bottom/right edges of my screen tiles?

Another Unreal bug. To get around it, make your tiles a bit smaller and adjust the master Screen actor's Width and Height properties and the other tiles' TileLeft and TileTop properties. This workaround has proven to fix this issue.

When I copy and paste slides, half of some text property's content is missing.

An UnrealEd bug, for a change. UnrealEd truncates text properties at the first double quote upon pasting. As a workaround for that, first paste your slide into a plain text editor of your choice and substitute all double quotes: Substitute the ones inside tags such as <img src="x"> with single quotes, <img src='x'>, and replace all double quotes in literal text by the &quot; entity. Alternatively paste the whole slide as is and then copy and paste the text properties one after one.

Must the scripted textures I create be located in a separate texture package?

No. They can also be located in the special MyLevel package like any other textures. Even the textures referenced in HTML can be in the MyLevel package as the parser automatically substitutes MyLevel by the actual package name.

Will scaling down my screen help improve my framerate?

Only in the same fashion as scaling any other texture would affect your framerate. Using fewer tiles in a tiled screen will improve your framerate, and using less complex HTML code on your ScreenSlidePage slides might help too. But in general, the size and amount of screens shouldn't have a noticable effect on your framerate.

Fading effects look chunky.

Keep in mind that images cannot be faded at all on scripted textures. If you are talking about text on your slides, you are probably not using an appropriate color palette; try PaletteGrayscale or PaletteColorscale from the ScriptedScreen.utx texture package for grayscale or primary color slides, or better yet create and import your own customized palette and assign it to the slide's Palette property.

The easiest way to achieve this is creating a full-color bitmap with one black-to-color gradient for each color that is to be faded in your favorite bitmap editor, converting it to 256 colors using an adaptive palette, cropping it to 1x1 pixels and importing it into UnrealEd as a texture; then assign it to the slide's Palette property.

Unreal stops responding for a second or so after loading my map.

Your ScreenSlidePage slides have to parse their HTML code. Unfortunately UnrealScript is not the fastest of all imaginable programming languages, and it is in particular not very well suited for parsing large amounts of text. Try optimizing your HTML a bit (in terms of reducing the total amount of tags and unnecessary whitespace). Create HTML that is fed into a ScreenSlidePage or a ScreenSlidePageWeb manually, not with FrontPage or DreamWeaver or other tools that are more intended for other kinds of browsers.

My page looks different on a screen than in Internet Explorer.

Right. ScreenSlidePage slides support only a very limited subset of valid HTML. See the [image] ScreenSlidePage documentation for details.

Will screens be able to download graphics in addition to text from the web?

Not likely. UnrealScript's support for drawing stuff on scripted textures is limited to text and textures. While I might be imaginative and figure out a way to draw individual colored pixels on a scripted texture, downloading graphics from the web still involves parsing their file format. UnrealScript is even less suited for parsing binary files than for parsing text.

Will screens support JavaScript? Java? Flash?

(No kidding, this has been asked.) No.


Screen

Screen : Creating a screen in a map

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

Creating a screen in a map

1 | Open ScriptedScreen.utx in the texture browser and apply any of the textures called Screen1 to Screen8 to the surface in your map that is supposed to display the screen. Make the surface unlit.

2 | Create a [image] Screen actor somewhere in your map.

3 | In the new Screen actor's properties, set the ScriptedTexture property (located under ClientScriptedTexture in the property sheet) to the name of the scripted texture you had used in the first step.

4 | Set the Width and Height properties to the desired pixel size of the screen area on the scripted texture. (That's not to be confused with the size of the scripted texture on your surface in world units; if you want to change how large the screen appears in your map, simply scale the texture.) If necessary, adjust the Left and Top properties to shift the content displayed on the screen.

5 | Create a [image] ScreenSlide actor of your choice somewhere in your map (near your Screen actor, for instance). Set the new actor's properties as it suits you.

6 In the previously created Screen actor's properties, set the SlideCurrent property in the Screen section to the name of the slide actor you created.

You can look up any object's name in the Name property in the Object section of its property sheet. Object names are created automatically and usually consist of the object's class name and a sequential number, like ScreenSlideMap23. Unfortunately there's no way to copy-and-paste an object name, so take a piece of paper and note the object name down.

That's it for a simple screen with a single slide. To add more slides, create more ScreenSlide actors and link them by setting their SlideNext properties to their respective successors.


Screen

Screen : Creating and using tiled high-resolution screens

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

Creating and using tiled high-resolution screens

Unreal's graphics engine imposes a size limit of 256x256 pixels on scripted textures. If you need larger (or higher-resolution) screens than that, you can split a large virtual screen into a number of smaller actual screens and tile them accordingly. One of those Screen actors will be the master screen and be responsible for things like slide animation, slide switching and rendering slides.

1 | Create as many screens as you wish to tile. Keep in mind that every screen needs its own scripted texture; if you need more than the eight from the ScriptedScreen.utx texture package, see the [image] custom scripted textures tutorial for how to create more.
2 | One of those Screen actors will serve as the master, all others are slaves. Set the slaves' TileMaster property to the name of the master Screen actor. Leave the master's TileMaster property set to None.
3 | Set the Width and Height properties of the master Screen actor to the total pixel width and height of the tiled scripted textures (not the total width and height of the screen brushes in world units). The slaves' Width and Height properties are ignored, so leave them as they are.
4 | Set the TileLeft and TileTop properties of all participating Screen actors, including the master screen, to the pixel coordinates (again, not the world coordinates) of the upper-left corner of their respective part of the complete picture.
5 | Set the master Screen actor's SlideCurrent property to the name of the first slide the complete screen should display. The slaves' SlideCurrent properties are ignored, so leave them set to None.

Unreal's graphics engine has some bugs in scripted textures that are most obvious with tiled screens. See the [image] frequently asked questions for more information and workarounds.


Screen

Screen : Creating a map surveillance slide

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

Creating a map surveillance slide

Implementing a map surveillance slide requires a little manual work on your side, but apart from that it is quite simple.

1 | Create a new [image] ScreenSlideMap actor.

2 | In the top view in UnrealEd zoom out until you have a nice view of your whole map. Press the PrtScr key on your keyboard (usually located above the Insert key) to take a screenshot.

3 | Open your favorite bitmap editor. Open a new bitmap document there and paste the screenshot into it.

4 Select the part of the screenshot that should be displayed on the screen and crop the bitmap to it (usually by chosing Crop from the Edit menu or something like that). Keep in mind the aspect ratio of the slide you are about to create, or the map might appear distorted.
Hint:

At this point it's up to you to modify the image as suits your map's theme—for instance, change the colors (inverting the whole picture creates a nice color scheme), erase unnecessary lines or add some text.

In order to make your neat new colors show up properly on the slide in the game, don't forget to set the Palette property (located under ScreenSlide in the ScreenSlideMap actor's property sheet) to the background texture you're just about to create. If you do that, the slide will use your texture's color palette and not its own rather coarse default one.

5 | Convert the bitmap to a palettized format (sometimes called 256 colors) and save it in PCX or BMP format. Add some padding to the edges of the bitmap to make its dimensions powers of two because UnrealEd won't import the bitmap otherwise.

6 | Open the texture browser in UnrealEd and click on the Import command in the texture browser's File menu. Select the bitmap you created (select All Files from the File Types drop-down list if your bitmap doesn't show up) and click Open.

7 | Enter MyLevel as the package name (in order to save this texture along with your level rather than in a separate UTX file) and an arbitary texture name. Click OK.

8 Now open the property sheet for the ScreenSlideMap actor you created before. Set the Map property to the name of the texture you had just imported, and set MapLeft, MapTop, MapRight and MapBottom to the world coordinates that correspond with the texture's upper-left and lower-right corner.
Hint:

Setting the MapTop, MapLeft, MapRight and MapBottom properties correctly is crucial for making a working map surveillance slide—otherwise the slide won't know which part of your map is supposed be displayed on it. Here's a trick for finding out the correct settings:

Select some actor (a path node will do) in the top view of your map and move it to the upper-left corner of what will be displayed on the slide. Open this actor's properties and look at the Location property in the Movement section. Take the value given for X and put it into the MapLeft property of the ScreenSlideMap actor. Then put the value of Y in the MapTop property.

After that, move this actor to the lower-right corner and put its X value into the MapRight property and its Y value into the MapBottom property.

9 | Adjust the other properties as it suits you.

If you didn't do that yet, create a Screen actor (see the corresponding [image] tutorial for details) and set its SlideCurrent to the name of your new ScreenSlideMap actor. Rebuild your map and next time you'll have a nifty screen showing all players in your map. If you want to exclude players of a given team, simply set their ShowColor flags to false in the slide's properties.


Screen

Screen : Screen Demo

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

Using the Screen demo in a map

A nice and easy way to give me credit for providing the Screen component is including the bundled Screen demo somewhere in your map.

1 | Create a screen that has a resolution of 256 pixels width and 128 pixels height. The size of the screen in world coordinates doesn't matter. Use the scripted texture named Screen1 for the screen surface, and make sure it is bottom-aligned on the surface. (See the [image] creating a screen in a map tutorial for details.)
2 | Open the texture browser and load or re-load the texture packages ScriptedScreen.utx and ScreenFonts.utx. That's a very important step in order to make UnrealEd aware of any textures in those packages you're not already using in your map. The demo will look not as it's supposed to if you omit this step.
3 | Select the Import command in the File menu (not the Brushes menu) and browse to your UnrealTournament\Maps directory. Select ScreenDemo.t3d and click the Open button. Check Import into existing map in the dialog that pops up and click OK.

Now you'll find a new Screen actor and a couple of slide actors around the center of your map. They're already selected, so use the opportunity and move them to a place where they don't bother you. That's it. Thank you.


Screen

Screen : Screen Textures

by Mychaeel

Mychaeel

http://www.planetunreal.com/screen

Creating custom scripted textures

The ScriptedScreen.utx texture package provides eight large scripted screen textures with black background and a color palette that represents colors from everywhere in the color space. However, if you want to use another background for your screen or a different default palette (or a differently sized texture, or just more scripted textures), you can easily create your own scripted textures for use with the Screen actor.

1 | Create a bitmap containing your desired background texture. Make sure it is palettized and its dimensions are powers of two (or UnrealEd won't import it). Save it in PCX or BMP format.
2 | Open the texture browser. Select the Import command in the texture browser's File menu and open the bitmap you created. Enter a new package name (or MyLevel if you want to include the new texture in your map) and a texture name that suits you. Click OK. After this procedure, the texture browser should display your newly created texture package containing your background texture.
3 | Select the New command in the texture browser's File menu. Enter a name for the scripted texture you are about to create and select ScriptedTexture in the Class drop-down list.
4 | In the Texture Properties dialog that pops up, set the ScriptedSource property that is located under ScriptedTexture in the property sheet to the name of your previously imported base texture. Close the dialog.


Using UnDox

By: E. Bruce Shankle III

E. Bruce Shankle III

This information applies to command-line versions of UnDox
Please visit the UnDox Home Page for the latest news.

Many people assume UnDox has a graphical user interface. It doesn't. In order to use UnDox you must first open a command prompt (Start/Programs/Accessories/Command Prompt) where you'll type UnDox followed by some other stuff then hit enter. This will only work, however, if the operating system can find the UnDox.exe program. It will find it if it's on the path. For those of you who are really new to this sort of thing (I've had many people email me about this), consider putting the file UnDox.exe in c:\windows or wherever windows is installed on your computer.

NOTE: IF YOU ARE USING UNDOX WITH UNREAL TOURNAMENT, YOU MUST EXTRACT THE .UC SOURCE CODE FROM UT'S PACKAGES. THIS IS DOCUMENTED HERE.

Here's how to use UnDox

UnDox Usage:
undox <package directory> <output directory> [noshow] [verbose] [inifile=<filename>] [stylesheet=epic|epic2|sun|<filename>] [EditPackages=<package name>]+

Examples: undox c:\games\unrealtournament c:\utdocs

undox c:\games\unrealtournament c:\utdocs noshow

undox c:\games\unrealtournament c:\utdocs stylesheet=epic2

undox c:\games\unrealtournament c:\utdocs noshow stylesheet="C:\My StyleSheets\s1.css"

NOTE: UnDox requires that your code compiles properly with ucc make. If ucc make gives you errors about your code, then UnDox will likely fail (or crash) since it doesn't do validation.

package directory

 Required. The full path to the location of the directory which holds unrealscript packages. Packages are considered any directory which contains a subdirectory named Classes. Given the following directory structure:
C:\UnrealTournament
|---Engine
|      |---Classes
|---Botpack
       |---Classes
you would use C:\UnrealTournament as the first argument to UnDox. This must be the first command line parameter. Note: If the path has spaces then you will have to enclose it in double-quote marks like this: "c:\program files\unrealtournament".

output directory

 Required. The full path to the location you want UnDox to write documentation to. There will likely be a lot (thousands) of files that will take up quite a bit of space (20 megabytes and up). So make sure this directory has plenty of free space. This must be the second command line parameter. See package directory parameter for note on spaces.

noshow

 Optional. If you supply noshow, then UnDox will not open up the index.html file. In this version this must be the third parameter. In later version this can the third parameter or later.

verbose

 Optional. If you supply verbose on the command line, UnDox will display a lot of output. This is useful if you experience a crash and are trying to isolate it.

inifilename

 Optional. UnDox will attempt to scan the UnrealTournament.ini file for EditPackages lines so that it can follow the same class-search pattern as the ucc compiler unless you give it a different ini file name with this setting. If no EditPackages lines are found in the file you specify, then UnDox will default to the package order which appears in a default install of UnrealTournament.

stylesheet

 Optional. UnDox allows you to control the appearance of the generated documentation by using cascading style sheets. UnDox includes 3 built-in style sheets: epic, epic2, and sun. The epic stylesheet is the default. With this setting you can also specify your own cascading stylesheet file which will be copied to stylesheet.css when UnDox runs.

EditPackages

 Optional. Multiple. Allows you to prepend package names the package search list UnDox uses when it tries to contruct class hierarchies. Use this in case you don't want to edit your UT ini files but still want to generated valid documentation. You may supply more than one of these arguments as long they are all seperated by at least one space like so:

EditPackages=Bot EditPackages=Engine

This site created and maintained by E. Bruce Shankle III
Copyright © 2000 Epic Games - ALL RIGHTS RESERVED


Creating Unreal Style Terrain in 3D Studio Max

By: Tyler A. Perry AKA Maverick

Maverick's Map Design

Email: maverick@planetunreal.com

Date: Monday, October 1, 2001 7:40 PM

Forward:

After searching for weeks, trying to find a tutorial on creating Unreal1 style, low polygon terrain, even emailing Epic Map Designers, and still getting nothing, I nearly gave up. I finally thought up a simple idea though.
At first, I didn't think it would work right, but I was desperate for a good looking terrain. With help from my friend Dan, or DRT-Salamander, I figured it out.
Now, like any other helpful mapper, I decided to write a tutorial on how to make terrain, because no one else deserves to go through the pain of searching like I did.

Abstract:

This tutorial will teach you how to create wonderful, Unreal style outdoor terrain in 3D Studio Max.

Assumptions:

First I assume you have Kinetix 3D Studio Max 3.0 or better (Since I have never used an oder version, I do not know how related 3.0 is to older versions).
3dmax is a very expensive peice of equipment for 3d artists, so if you just want a one time terrain, then this tutorial is NOT for you! Instead, email me a small plan of it, and I'll see if I can make what you want. (This is only if you REALLY need the terrain, I cannot do this every day for people).
I also assume you know how to use 3D Studio Max, and not just the basics, but intermediate and a little advanced stuff about it as well, I can't explain everything to you.
I assume you know how to import stuff into the editor.

Tutorial:

In 3dmax. First, create a box, about 200x200x100, and no linesegments. This will be your sky, you won't do too much with this at the moment, just wait though!
Now, create a cylinder, just under the box, with the dimensions 60x -75, with 1 heightcap and 2 cap segments. You want the cylinder to have 10 sides. Your windows should look like this:

Now that we have the basic stuff layed out, let's turn this into one mesh. Click on the create tab (the arrow) in your Tab Panel, then, click the dropdown window that says Standard Primatives and select Compound Objects. Click Boolean:

Under operation, you should see a list of different operations you can choose, click on Union, then, under Pick Boolean, click the button labeled "Pick Operand B", then select the cylinder, the two meshes should combine together like this:

You're almost ready to make it look like a terrain! Click the Modify Tab, (it looks like a blue rainbow), and, if you see the button, click Normal, if you don't, click the button labeled 'More', and select it. You now want to Flip the Normals. Your mesh should be inside out, like this:

Now it's time to do the real fun stuff! Rightclick on your mesh, then select Convert to Editable Mesh. Once you have done that, under selection, click Vertexes. You can choose to click ignore backfacing or not, but I prefer editing the vertexes seperately.
The vertexes you want to edit are the ones that are on the top of the cylinder. Screw around, until you get anything similar to this:

*Note: I turned off smooth and turned highlighted facets on so you could get a better view of what it looks like.

Once you have made your terrain, save it, and export it as a DXF file, then import it into UnrealEd. (If the mesh is screwed up, go back into 3dmax, and click normal again, and flip).

I hope this tutorial helped you out a bit! I was in a bit of a rush, so it isn't perfect, but at least you get a look at how to do it! A quick tip, optimize the mesh if you want.

This design is copyright© 2000-2001 and 2002 to Tyler A. Perry AKA Maverick, please do not copy it. If you have questions, please email him at maverick@planetunreal.com


3DS Max Terrain For UEd2

By: Adam ‘Muad'dib’ Stiles

http://www.planetunreal.com/muad

muad@planetunreal.com

PRE-REQUISITES:
Understanding of 3D Studio Max 3 or 4 (I'm using 4)
You'll also need a copy of above said software ;)
Photoshop 6.0 (or your favorite bmp editing software)
The typical UnrealEd 2 knowledge.

After hanging out at forums and such, one question that I've noticed that happens to pop up quite often is "How do I do terrain in Unreal Ed?" There are several ways to approach this question - one would be to tackle the terrain directly by using the vertex editing and clipping capabilities of UEd. However, what some people seem to forget (or now know in the first place) is that UEd is capable of importing DXF files - which means that one can model brushes in any 3d software package that will export to the DXF format. Today we're going to do exactly that by doing some quick and dirty terrain in 3DS Max 4.

Note that this may not be the most elegant way of doing things - nor the most comfortable - I should also note that it's based, in part, on a tut I found by some of the folks at Legend (Wheel of Time, currently Unreal 2). But it certainly works and provides for a bit of flexibility. Now lets get started. First thing to do is fire up 3DS Max 4...

With 3DS Max going, we first need to create a box - this will be the basis for our terrain. We're going to "mold" it into terrain brush. So on your Create tab, click the Geometry button, select "Standard Primitives" from the drop down list, and click "Box"

You'll see some stuff show up. Expand the "Keyboard Entry" rollout and type in 256 for Length, Width, and Height (NOTE: these are example numbers, you can use what you like, but stick with hex multiples - like 256, 512, 1024, etc) - then click the create button. You'll have a nice 256 unit cube in your viewport.

Now in your Perspective Viewport, right click the words "Persepective Viewport" and choose Edged Faces. Make sure the cube is selected and click the Modify Tab. Apply a "Normal" modifier to the box and click "Flip Normals" This will let you see the brush as it will look in UEd when you subtract it.

Now apply an "Edit Mesh" modifier to the box. Select "polygon" as your sub-object level by pressing on the polygon button.

Make sure you check the "Ignore Backfacing" option and select the bottom side of the box like so:

This is where we'll actually build the terrain. Now with that side selected, add a "Tessellate" modifer to that side. In it's options tell it to operate on Polygons, give it a tension of 0, and an iteration of about 4. You should have a nice grid on that side now like this:

To actually create our terrain we're going to use a heightmap. A height map is just a bitmap that tells the software where "high" and "low" terrain is. The color black is considered "low" and white is "high". So fire up Photoshop. NOTE: I'm doing an example for Photoshop here - know that you can use any paint software you like and paint your height map in any fashion you choose :) Create a 256 x 256 image in RGB format - fill it with White. Goto Filter->Render->Difference Clouds. Now goto Image->Adjust->Equalize. Save this image as a bitmap and remember where you saved it! :) You can close Photoshop now.

Back to 3DStudio Max 4. You should have a box, with a grid on the bottom. Now apply a "Displace" modifier to that bottom side. You'll see the options like this:

Click the "None" button under Image: Bitmap: - point it to the image you just created in Photoshop. It'll look like nothing happened to your box. Now adjust the Displacement: Strength to about 50 (you can play with this number to your fitting). Viola! Terrain! Now we need to clean it up and export it!

Add another "Normal" modifier and click "Flip Normals" - now the brush will be understandable to UEd. Apply another "Edit Mesh" modifier. Now right click in the Stack dialog like so :

And select "Collapse All". If it gives you a warning about losing the stack information then just choose "yes" to do it anyways. You should have an editable mesh as a result in your stack. Now goto File->Export. Select "AutoCAD (*.DXF)" as the save-as type and give it a name - tell it to Save To Layers in 1 Layer. You may want to save this as a MAX file as well so you can open it up easy later if you want to change anything. You can close Max down now.

Open up UnrealEd. Goto Brush->Import. Select the DXF file you just created, and select "Solid Mesh" under the Solidity option. You can now resize the brush however big ya like - just resize, select a texture, and subtract the brush!

NOTE: you can also, of course, do the usual edge turning and vertex editing tricks to tweak your terrain into submission if you're knowledable and so inclined.


Making a Chess Type Tile

By: Rogelio Olguin

Rogelio Olguin

Desp's Padrisimos

What you should know:

You should know where filters are and how to have basic idea of the things in Adobe Photoshop. Just a basic knowledge of where to go around this program.

1# first step is open Abobe Photoshop duh:)

2# Go to file than new than when the window opens up use a pixel size of 128 v 128 with white background.

3# Go to layer and create a new layer. Once that is done get a color RGB of 133, 124, 110 and you have grayish/brownish type annoying color right? if so just use the paint bucket and drop the color into the new layer.

4# ok your texture is done! j/k (that was really corny) ok now go to the filters/noise/add noise add about 12% of noise... I know looks really bad.

5# in this way you can really go both ways here with go to filters and use blur to blur it around 3% or so or just get the blur tool around 20% and do only some spots. I like the blur tool more because this way you can blur some areas more and some areas leave them nice and grainy.

something like this

6# Now go to image/adjust/levels put this on the three input levels 0, 2.3 , 169 and now it looks like this.

7# ok now is the fun part:) go to layer/layer style/bevel & emboss yeah now you see some neat roundness in the texture. Ok no to change the settings in depth make it max in size make it "0" even though it is "0" it still shows a little bevel on it.

8# Now go to layer and flatten... this flatten command makes both layers come to one so it is one texture. Ok now go to filters blur/blur this will blur just enough that some of the ugliness of it is gone. ok now go to sharpen and sharpen more two times should bring back some grain again.

9# Now go to image/adjust/ hue saturation put all of the saturation to -100 this makes B&W. With out putting in grey scale.

10# now select the select tool or crop tool to crop all of the picture. than edit/copy. Go to file/new and make a 256 v 256 size canvas once you have that open select inside it and go to edit/past. The cropped picture appears inside the 256 v 256 canvas. Move the picture to the top right of the canvas so the side fits perfectly in the right top corner. like this...

11# now what we have one tile on the right corner of our canvas... ok now go to layer/new/layer and keep placing the tiles around intill you get something like this.

12# now you have a tiled work or art * cough* shit.... but looks dumb without any other details right? ok Detail now but before detail this is meant to be a chess tile... ok here goes. Go to windows/show layers... if you have that window open... good : ) now you can select the layer you want select the top left one now.

13# now go to image/adjust/brightness contrast. now move it around in till you get a nice dark color not all the way black but grayish. your choice really. now do the same with the lower right one. Remember you have to select that one with the window/show layers window. it should look like this...

14# Ok now flatten the whole thing and lets add some detail things. Once flattened go to your lasso tool it is one of the select tools. ok go insane and just select all over the the texture and than just let go it leaves some lasso marks if it does not select much redo it also use a "feather" of 2 to give it some mixing to it (the feather should be in the top task bar). now that you have good amount selected that you can work with and looks like a really odd selection now you can use the level again and change the tint to the selected part lighter just to change the lightness of it or darken it. It might look like this...

15# Ok now for smaller detail lets make some cool cracks. select a piece as shown in the picture below...

Once Selected comes a cool part again. go to edit copy/past. hmm nothing happened... :( no worries :) go to layer/layer style/inner shadow. Now your see something cool your see a crack on the floor looks neat ehh? Yep the fun part:) ok now just mess around with that once your done make more cracks with the same process diff types and stuff. here is the almost final textures. Bwhwhaha you thought you where done :) small note when trying to get more cracks you have to go back to original tile layer by the layer window.

some cracks

16# flatten again. Now you can either select the seams in the tiles and make them darker or just leave them like this. you can also change the colors by using image/adjust. color balance by selecting each tile and changing them to what you want. here are few color changes I did...

Tips: Sometimes you have to darken areas again and re touch like on the white area the grain was to much so I blurred it again and darken the cracks.

Practice makes prefect these same techniques can be used in other kind of textures. just test use filters test out a lot it takes patients but in the far run it pays of if you are serious in wanting the learn these things of graphic design. later in till the next Tutorial have fun : )


Tiling a photo taken texture for use in games

By: Rogelio Olguin

Rogelio Olguin

Desp's Padrisimos

What you should know:

You should know where filters are and how to have basic idea of the things in Adobe Photoshop. Just a basic knowledge of where to go around this program.

Tip#1: When using a camera to take textures try to make it as straight as possible so the edges of the texture you are trying to take are not angled wrongly that saves you more time and grief.

Tip#2: Do not take with flash at all. flash photos suck and really can not be used right.

Tip#3: try to take photos of walls floors but not hall ways nothing that has depth or perspective in it.

-Right------------------wrong-

1# Ok now that those tips are done for we can start trying to tile this. First of use the right brown brick one right click/save as while your mouse curser on the texture. and open it up ion PS.

2# Now while it is open select the whole picture with the lasso tool and edit/copy/past now you have two layers the background one and the new one that looks the same.

3# Now go to edit/transfer/flip horizontally and the texture flipped to the other side. Remember you have not flipped the background one so it is in the same way you left it. Do not flip the background one OK!! :)

4# Now get the erase tool and select a brush size of "200" and erase amount 100% now go to the right top corner and leave your mouse button pressed and erase down wards to the right lower corner.

Note: This is tiled left to right now sometimes you can leave it like this because you might have trim going left to right on the top and on the bottom. But in this case the Trim is not on the texture so we must tile it both ways horizontally and vertically.

4# Now You have a horizontal tiling of this texture, but it need a vertical one. Go ahead a flatten the whole thing to go to the next step.

5# Select the whole thing again and go edit/copy/past than go edit/transfer/flip vertically. Now the Texture is flipped should look like this. not flattened!

5# Like in the other one you still have have a texture right below it that you can not see yet. Ok now use the select line tool and go from the lower left corner and make line of section to the middle than make another line of selection to the right lower corner. makes a line like so with out the red lines duh: ) just the white cutting lines...

6# now you have pyramided selection just go edit/cut and leave it cut no pasting at all. here is how it looks now...

7# now it tiles perfectly :) But what are you saying it has seams???... yeah it has them and? ok ok now to take the seams out. get the erase tool of a brush size of 45 and now follow the seams gently it by erasing it slowly makes the texture into one.

Note: Do not go to the left or right edges when erasing if you do that all what you have worked for is gone.

Tip#4: To test tile go and open a new canvas if the texture size of your old one was 256 v 256 make it 512 v 512 now go back to your tiled texture select all of it and than go to the 512 v 512 canvas and past four times and put them so it all of them fit perfectly on the top left another top right and so on....

now your are done and this is the final product I put two right beside each other to show you how it tiles...

Thanks for reading on how to tile till the next one later all : )


Brushed Metal Textures

by: M

In this tutorial, you will learn how to make a simple texture, import it to UnrealEd, and apply it to a surface. You will not learn advanced texture placement or other advanced texturing functions of UnrealEd.
This tutorial assumes that you own and have experience with Paint Shop Pro 5, but this tutorial will work with other graphics programs as well. It also assumes that you have basic knowledge of the UnrealEd Beta.

Creating the Texture

First, open Paint Shop Pro 5 and create a new image (File-New) that is 400x400 pixels and 24-bit color. Flood fill this image with a solid, dark grey color. Now add noise to the image (Image-Noise-Add...), and type the number 100 into the "%Noise:" field. Select all (Selections-Select All) and make the image grey scale (Colors-Grey Scale.) After doing this, you will have grey noise, but not brushed metal. The next two steps are very important. To add the brushed look, apply motion blur (Image-Blur-Motion Blur...) to the image and type 25 into the Intensity field. You can also change the direction of the motion, but it is not necessary. Now, soften the image (Image-Blur-Soften More) and you have brushed metal. This effect may not look perfect, but feel free to apply more motion blur or softness to the image until you get the effect you want. To get the texture to look good tiled, select a chunk out of the middle of the image and make it a seamless pattern (Selections-Create a Seamless Pattern.) Now resize the image so that the dimensions are equal powers of two, preferably 256x256. Finally, save this image as a Zsoft Paintbrush (.pcx) Version 5 file in you Unreal textures directory.

Importing to UnrealEd

Load up UnrealEd if you hadn´t already while working on the texture, and make sure the Browser is on the Textures menu. Click the Import button on the bottom of the screen below the texture browser and open your texture that you just created. Keep all the information on the window that just popped up the same and click Ok. This will create a new packet called "Untitled" with your texture in it. To apply this texture to a surface, simply highlight the surface and select the texture from the texture browser.

Important Notes

For a texture to be imported into UnrealEd, the texture´s dimensions must be equal powers of two. For example, 32x28 will not work, but 32x32 will. Common dimensions include 512x512, 256x256, 128x128, and so on.
This tutorial was to introduce the beginner to importing textures and applying them. I am planning on doing an advanced texture manipulation tutorial later that will include resizing, aligning, detail maps, and other advanced items.
If you have any comments, questions, or suggestions on this tutorial, please send them to me, m_seefeldt@hotmail.com, not the webmaster of this site.


Pathlogic

Pathlogic V1.03-R0 - Pathnoding Utility

By: Robert Wey

Robert Wey

Here's another great utility from the author of the TextAlign tools, Robert Wey. This one allows you to place pathnodes in your map's not using UnrealEd but by actually walking around your map while in UT itself!

This is the PC Version Download TerraEdit (20 kb)

!!! See section VI for a quick view of what's changed.

!!! Special thanks to JTRipper for suggesting the change that allows inventory to be picked up. Thanks JT!

Table of Contents:

I. Description
II. Installation
III. PathLogic Console Commands
IV. Using
V. Elevator Mode
VI. Revisional History
VII. Disclaimer and Legal

I. Description

PathLogic is combination Windows EXE and a UT script file that allows you to place nodes and other various navigation points in your map while playing the map...rather than in UnrealEd. The obvious advantage to this is the time required to lay the paths. While pathing in your map, all pathnodes you place as well as preexisting pathnodes are visible. You can either place pathnodes manually or automatically as you walk. The interval at which nodes are placed automatically is fully adjustable during gameplay and all placements are checks for crowding. Once placed, a nodes can then be erased if desired. Reading the following sections in their entirety will explain all the features you can control.

II. Installation

1) Copy PathLogic.u to your UT\System directory.
2) Copy PathLogic.exe to a directory of your choice.
3) Although PathLogic alters, then restores your User.INI file, its probably a good idea
to make a backup of USER.INI before using PathLogic.

NOTE: PathLogic scans your registry for the UnrealTournament directory. If, upon starting PathLogic.exe, it displays the message "Can't find UT directory", you can add (at your own risk) the following string entry to your registry to resolve the problem:

[HKEY_LOCAL_MACHINE\Software\Unreal Technology\Installed Apps\UnrealTournament] "Folder"="C:\\UnrealTournament"

The registry entry above adds a string value called "Folder". The actual path specified ("C:\\UnrealTournament" in the above example) will vary depending on your UT installation.

III. PathLogic Console Commands

Pathnodes are placed while you PLAY your map...not from within UEd. You command it via console commands and, thus, it's strongly recommended that you bind the following to some keys for quick access. Commands PathLogic understands are:

PathMode n Where n is 0, 1, 2, or 3.
0 = Manual Mode. Must tell it place a pathnode.
1 = Auto Mode. Nodes are placed at intervals as you walk.
2 = Erase Mode. Run into them and they're erased.
3 = Elevator Mode. Autoplace of LiftExit/LiftCenters

Default is 0, Manual Mode.

SelectPathType Cycles through Normal Pathnodes, One-way Pathnodes, and Alternate Pathnodes. A message will display current selection.

Default is Normal pathnodes.

APathRo n Specifies the AlternatePath bReturnOnly value. Where n is 0 or 1

APathWt n Specifies the AlternatePath SelectionWeight value. Where n is the desired value.

APathTm n Specifies the AlternatePath Team value. Where n is 0 - 3.

AutoPathSpacing n Where n is a "world units" spacing value. Determines how far apart auto nodes will be placed. Default is 350.

MinimumClearance n Where n is a "world units" spacing value. Determines clearance checking distance to prevent placing nodes too close together. Default is 64.

DropPathnode Manually place current path type pathnode at your current position.

DropPlayerStart Place a player start at your current position.

In order to make PathLogic easy to use, it is strongly recommended than you bind at least a couple of AutoPathSpacing commands to keys. Being able to quickly switch this value is is very helpful when traversing varying geometry in your map. Have a couple (at least) of AutoPathSpacing along with the mode switch and the drop commands. Doing this will give you much quicker control over the process. The following is an example of some possible key bindings that replace the default player view bindings with PathLogic bindings:

NumPad0=DropPathNode
NumPad1=AutoPathSpacing 128
NumPad2=AutoPathSpacing 256
NumPad3=AutoPathSpacing 350
NumPad4=PathMode 3
NumPad7=PathMode 0
NumPad8=PathMode 1
NumPad9=PathMode 2
NumPadPeriod=DropPlayerStart
GreySlash=SelectPathType

IV. Using

1) Build your map up to the point where you want to add pathnodes. Its better to have all weapons and pickups in place, but not necessary. Place one playerstart in the map. Build your map (make sure to define paths), save it, and exit UEd.

2) Run PathLogic. A message will appear asking if you want to run Unreal Tournament in PathLogic mode. Answer Yes to proceed.

3) PathLogic will minimize itself to your taskbar and will luanche UT. Start a practice session on the map you want to pathnode. Make sure to turn off ALL mutators. During the flyby intro, make sure NOT to accidently add any pathnodes as these will also be considered for your map and will either wind up hanging in the air or off the map. When your map starts, you will be in Manual Mode. Any preexisting pathnodes will be visible.

4) Use the different commands listed in Section III as necessary. Avoid a lot of erasing. PathLogic will only record 2048 nav points. This number may increase in later revs.

5) You can fly while your in the game and even ghost. Autopathing is inhibited while flying or falling.

6) When you're done, simply exit UT and then pull up PathLogic from the taskbar.

7) Press "Make Path Map" to exit PathLogic and have it generate a path map. Press Cancel to bypass building the path map.

8) Reload your map in UEd and Import PLMap.t3d from your Maps directory. Make sure to check mark "Import to existing map", then hit OK. UEd will pull in all nodes you left behind in the last pathing session. You can then edit/tweek these as necessary.

V. Elevator Mode

Elevator mode can autoplace LiftExits and LiftCenters on Movers. This placement, however, is limited to movers with an Object/InitialState of StandOpenTimed. Follow these steps to add two lift exits and one lift center to an elevator.

1) Approach the elevator and stop where you want the "rest postion" lift exit to be placed.

2) Switch to PathMode 3 (Elevator Mode). Upon switching to this mode, a LiftExit will be placed where you stand. A message will appear indicating Elevator Mode and will also display the mover tag it thinks you're dealing with. If this tag is incorrect, switch to Erase Mode and erase the tag. If it is correct, proceed (step 3).

3) Step onto the elevator in question. You will have 4 seconds to position yourself in the center of the elevator where you want the lift center to be placed.

4) Ride the elevator to the top and climb out the direction desired, then stop where you want the second lift exit to be placed. Change to any other mode (i.e. Manual Mode) and the second lift exit will appear.

How it works:
When you change to elevator mode, PathLogic searches for the nearest visible mover with an Object/InitialState of StandOpenTimed. If it can't find any within 512 units, a message will be displayed and your mode will not change from what it was. If does find one, it remembers its Event/Tag, displays that, then creates the first LiftExit setting its LiftTag accordingly. Next, PathLogic waits for the elevator to be triggered and four seconds later, when the elevator starts moving, it places the lift center.

NOTE:

when you first start the game, all StandOpenTimed elevators have a four second delay added to whatever their current delay is. This gives you time to get yourself centered on the elevator. Finally, when you step off the elevator and change out of elevator mode, it will only place a second lift exit if a lift center was placed. Thus, it is possible to add more than two lift exits by simply entering Elevator Mode near the elevator in question and then never riding the elevator...rather, just change to another mode. When you do this, as always, verify the elevator Event/Tag on the readout.

Problems:
If you have a HUGE elevator and it says "Can't locate elevator" ... even though you're sure your standing within 512 units, its likely the origin of the mover brush is more than 512 units away. PathLogic only uses the mover's origin to measure distance. In these cases, you'll have to place the first lift exit within 512 of the origin (even though that may not be where you want it), and reposition it later in UnrealEd.

VI. Revisional History

1.00 Initial release.
1.01 Added custom sprites for nodes. Executable can be run from any directory. Launches UT. Prints path stats when path map is built. Launches in Manual Mode.
1.02 Inhibits autoplace if flying or falling. Fixed missing error message when could not find UT directory...now shows message. Implements elevator LiftExit/LiftCenter.
1.03 Added support for AlthernatePaths. No longer disables inventory from being picked up. Console command OneWayPath(n) changed to SelectPathType. Added console command APathProperties.

VII. Disclaimer and Legal

Digital Innovations, Inc. offers this freeware utility "As Is". We will not be held responsible for any damages, loss of time, business, etc. resulting from the use or misuse of this product. You may distribute this program as freeware provided the archive remains intact. You may not, under any circumstances, distribute this product for sale or profit either directly or indirectly without the prior written consent of the author.

If you have any questions regarding this utility, please contact the author Robert Wey


UnrealEd 2d Actor Menu

UnrealEd 2d View Menu - Actor

This is the default view. It will show each actors unique icon and meshes for actors that have them

This view will show all actors as generic icons.

This view will show the radius of the selected actor. It helps for setting the collision radius of triggers, and the light radius of lights. But that's another tutorial :)

This view hides all actors, showing only the brushes.

Wolf's Unreal


UnrealEd 2d View Menu

This menu will let you select which brushes are shown in the 2D view. The image above shows the default setting and this is where you will usually leave it. The check mark indicates it is set on. It should be self-evident what each does. The Active Brush is the Red brush and moving brushes are special brushes (like doors, lifts*). Backdrop and Coordinates do not apply, and Paths is used for showing the paths defined with path nodes (the paths that bots and monsters use to get round the level)--again, a future tutorial.

* Note: Moving brushes are ALWAYS rendered in "wire-frame" mode.

Wolf's Unreal


UnrealED Keyboard Shortcuts

Keyboard Shortcuts
Special mouse clicking combinations

A + right mouse click: Add actor there.
L + right mouse click: Add light there.

Shortcut keys

Delete: Delete selected actors.
1, 2, 3: Slow, medium, and fast movement speed.
F1: Help.
F4: Actor properties.
F5: Surface properties.
F6: Level properties.
F7: Compile changed scripts.
F8: Rebuilder.
B: Toggle brush visibility in the current viewport.
H: Toggle actor visibility in the current viewport.
P: Toggle player controls or real-time update of the viewport.
Shift-A: Select all actors.
Shift-B: Select all surfaces belonging to the selected surfaces' brushes.
Shift-C: Select adjacent coplanar polygons.
Shift-D: Duplicate selected actors.
Shift-F: Select adjacent floors.
Shift-G: Select surfaces belonging to the selected surfaces' groups.
Shift-I: Select surfaces with items matching the selected surfaces' items.
Shift-J: Select all adjacent surfaces(flood-fill).
Shift-L: Look ahead in the current viewport (no pitch or roll).
Shift-M: Memorize selected surfaces.
Shift-N: Select none.
Shift-O: Select surfaces from intersection of selected surfaces and memory.
Shift-P: Select all surfaces.
Shift-Q: Reverse the set of selected surfaces.
Shift-R: Recall memorized surface selection.
Shift-T: Select all surfaces which use the current texture.
Shift-U: Select union of selected surfaces and memorized surfaces.
Shift-W: Select adjacent wall surfaces (flood-fill).
Shift-X: Select exclusive or of selected surfaces and memorized surfaces.
Shift-Y: Select adjacent slanted surfaces.
Shift-Z: Select none.
Ctrl-A: Add brush to world.
Ctrl-B: Load brush.
Ctrl-C: Copy.
Ctrl-D: Deintersect brush with world.
Ctrl-E: Save as.
Ctrl-L: Save level.
Ctrl-O: Load level.
Ctrl-P: Play level.
Ctrl-N: Intersect brush with world.
Ctrl-R: Redo.
Ctrl-S: Subtract brush from world.
Ctrl-V: Paste.
Ctrl-W: Duplicate.
Ctrl-X: Cut.
Ctrl-Z: Undo.

Wolf's Unreal


Properties Menu

Properties Window

This is the a generic Properties Window in UnrealEd. You can open this dialog for ALL actors. Though each Properties window looks the same there are specific fields that pertain only to that actor and those fields are unique to that actor's Properties Windows.

This is the Properties Window for one of Barrels in out level. Note the similarities with the generic window above, but note the differences. I have highlighted the actor-specific fields, which are the ones you should be concerned with for this actor.

Here I have highlighted the actor-specific fields for a light actor.
Note: Light Color and Lighting appear in all the Properties windows, but most actors will not emit light.

Wolf's Unreal


Rebuilder

This is the Rebuilder window. Some of the numbers in this window will be useful later on when you have more experience with level editing. These properties won't update until you rebuild.
The easiest (and best) way to rebuild is to simply click the Rebuild Geometry button. If you leave everything else at its default setting it will automatically rebuild the geometry, run the BSP and render the lighting. If Auto-BSP is checked in the Geometry window, then it will automatically run, and if Auto-Lighting is checked in the BSP window then it will automatically run. The BSP "cuts up" the polygons for rendering, and Lighting renders the lighting for the level. There are individual settings for each of these accessed by the tabs at the top of the window, but it is best to just leave them alone.

These are the other tabs in the Rebuilder window.

Wolf's Unreal


UnrealED Tool Bar

Tool Bar

This is the Tool Bar with its Icon's labeled
  1. Move camera
  2. Zoom camera
  3. Add brush to world
  4. Rotate brush
  5. Shear brush
  6. Subtract brush from world
  7. Scale brush
  8. Stretch brush
  9. Brush intersection
  10. Snapscale brush
  11. Select all polys
  12. Brush deintersection
  13. Select all actors
  14. Select actors inside brush
  15. Add special brush
  16. Select none
  17. Invert actor selection state
  18. Add movable brush
  19. Replace selected brushes
  20. Replace selected nonbrush actors
  21. Build a cube
  22. Undo last operation
  23. Redo last operation
  24. Build a sphere
  25. Pan textures
  26. Rotate textures
  27. Build a cylinder
  28. Drawing region: selected actors
  29. Drawing region: off
  30. Build a cone
  31. Hide selected actors
  32. Drawing region: brush Z(depth)
  33. Build a stair
  34. Nothing
  35. Toggle vertex snap
  36. Build spiral stair
  37. Get help
  38. Camera speed
  39. Build curved stair
  40. Toggle grid
  41. Toggle rotation grid
  42. Build a sheet

Wolf's Unreal